package com.airlock.iam.flow.shared.application.configuration.item;

import com.airlock.iam.core.application.configuration.contextdata.BooleanContextDataItemNameConfig;
import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.exception.PropertyTypeMismatchException;
import com.airlock.iam.plugin.api.valuereader.BooleanPropertyValueReader;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(description = "User context data item that stores a boolean value.", displayName = "Boolean User Context Data Item")
public final class BooleanContextDataItemDefinitionConfig implements ContextDataItemDefinitionConfig<Boolean> {
   @PluginProperty(description = "The context data item in the context data.", optional = false)
   private BooleanContextDataItemNameConfig contextDataName;
   @BooleanProperty(
      description = "Specifies whether this context data item is required for the step to validate successfully.",
      defaultValue = "true",
      optional = true
   )
   private boolean required;
   @BooleanProperty(description = "If enabled, only 'true' is considered a valid value.", defaultValue = "false", optional = true)
   private boolean valueMustBeTrue;
   private static final String VALUE_MUST_BE_TRUE = "valueMustBeTrue";
   @BooleanProperty(description = "If enabled, only 'false' is considered a valid value.", defaultValue = "false", optional = true)
   private boolean valueMustBeFalse;
   private static final String VALUE_MUST_BE_FALSE = "valueMustBeFalse";

   @Override
   public String getContextDataItemName() {
      return this.contextDataName.getContextDataName();
   }

   @Override
   public Class<Boolean> getType() {
      return Boolean.class;
   }

   public BooleanContextDataItemNameConfig getContextDataName() {
      return this.contextDataName;
   }

   @Override
   public boolean isRequired() {
      return this.required;
   }

   public boolean isValueMustBeTrue() {
      return this.valueMustBeTrue;
   }

   public boolean isValueMustBeFalse() {
      return this.valueMustBeFalse;
   }

   @Override
   public Optional<String> getInputPurpose() {
      return Optional.empty();
   }

   @ConfigurationValidator
   public static void checkValiatorProperties(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context, Environment valEnv) throws PropertyConstraintViolationException, PropertyTypeMismatchException {
      boolean valMustBeTrue = BooleanPropertyValueReader.effectiveBooleanPropertyValue(pc, "valueMustBeTrue", env, context);
      boolean valMustBeFalse = BooleanPropertyValueReader.effectiveBooleanPropertyValue(pc, "valueMustBeFalse", env, context);
      if (valMustBeTrue && valMustBeFalse) {
         throw new PropertyConstraintViolationException(
            "valueMustBeTrue", pc, env, context, "Value to be validated cannot be 'true' and 'false' at the same time."
         );
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public static BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder builder() {
      return new BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public BooleanContextDataItemDefinitionConfig() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public BooleanContextDataItemDefinitionConfig(
      BooleanContextDataItemNameConfig contextDataName, boolean required, boolean valueMustBeTrue, boolean valueMustBeFalse
   ) {
      this.contextDataName = contextDataName;
      this.required = required;
      this.valueMustBeTrue = valueMustBeTrue;
      this.valueMustBeFalse = valueMustBeFalse;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class BooleanContextDataItemDefinitionConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private BooleanContextDataItemNameConfig contextDataName;
      @SuppressFBWarnings(justification = "generated code")
      private boolean required;
      @SuppressFBWarnings(justification = "generated code")
      private boolean valueMustBeTrue;
      @SuppressFBWarnings(justification = "generated code")
      private boolean valueMustBeFalse;

      @SuppressFBWarnings(justification = "generated code")
      BooleanContextDataItemDefinitionConfigBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder contextDataName(
         BooleanContextDataItemNameConfig contextDataName
      ) {
         this.contextDataName = contextDataName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder required(boolean required) {
         this.required = required;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder valueMustBeTrue(boolean valueMustBeTrue) {
         this.valueMustBeTrue = valueMustBeTrue;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder valueMustBeFalse(boolean valueMustBeFalse) {
         this.valueMustBeFalse = valueMustBeFalse;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BooleanContextDataItemDefinitionConfig build() {
         return new BooleanContextDataItemDefinitionConfig(this.contextDataName, this.required, this.valueMustBeTrue, this.valueMustBeFalse);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "BooleanContextDataItemDefinitionConfig.BooleanContextDataItemDefinitionConfigBuilder(contextDataName="
            + this.contextDataName
            + ", required="
            + this.required
            + ", valueMustBeTrue="
            + this.valueMustBeTrue
            + ", valueMustBeFalse="
            + this.valueMustBeFalse
            + ")";
      }
   }
}
