package com.airlock.iam.plugin.configeditor.field;

import com.airlock.iam.plugin.configeditor.data.ConfigurableProperty;
import com.vaadin.v7.data.Property;
import com.vaadin.v7.data.util.TransactionalPropertyWrapper;
import java.util.Optional;
import java.util.function.Function;

public final class ValueMapperPropertyAdapter extends TransactionalPropertyWrapper<Object> {
   private final Function<ConfigurableProperty, Object> valueMapper;

   public ValueMapperPropertyAdapter(ConfigurableProperty delegationProperty, Function<ConfigurableProperty, Object> valueMapper) {
      super(delegationProperty);
      this.valueMapper = valueMapper;
   }

   public static Optional<Property<?>> fromPropertyDataSource(Property<?> property, Function<ConfigurableProperty, Object> valueMapper) {
      ConfigurableProperty configurableProperty = getConfigurablePropertyFromProperty(property);
      return configurableProperty != null ? Optional.of(new ValueMapperPropertyAdapter(configurableProperty, valueMapper)) : Optional.empty();
   }

   private static ConfigurableProperty getConfigurablePropertyFromProperty(Property<?> newDataSource) {
      if (newDataSource instanceof TransactionalPropertyWrapper) {
         Property<?> wrappedProperty = ((TransactionalPropertyWrapper)newDataSource).getWrappedProperty();
         if (wrappedProperty instanceof ConfigurableProperty) {
            return (ConfigurableProperty)wrappedProperty;
         }
      } else if (newDataSource instanceof ConfigurableProperty) {
         return (ConfigurableProperty)newDataSource;
      }

      return null;
   }

   public Object getValue() {
      return this.valueMapper.apply(this.getConfigurableProperty());
   }

   private ConfigurableProperty getConfigurableProperty() {
      return (ConfigurableProperty)this.getWrappedProperty();
   }
}
