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

import com.airlock.iam.core.misc.cronto.CrontoHandler;
import com.airlock.iam.flow.api.application.configuration.selection.FlowConditionConfig;
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.license.PluginLicenseRestriction;
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.ConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.valuereader.PluginPropertyValueReader;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.function.Function;

@Plugin(
   description = "<p>Flow condition that determines if the Cronto device used during login (or registered during the authentication flow) can be activated for push. It also considers the \"Push Notification Reminder Period\" property of the Cronto handler to determine if the user should already be asked again.</p><p>This condition is only useful in authentication flows and after a Cronto authentication or activation step.</p>",
   displayName = "CrontoSign Swiss Push Activation Possible"
)
@PluginLicenseRestriction(moduleAffiliation = "Cronto")
public final class CrontoPushActivationConditionConfig implements FlowConditionConfig {
   public static final String PUSH_ACTIVATION_CONDITION_NAME = "CrontoSign Swiss Push Activation Possible";
   @PluginProperty(description = "Plugin to handle all Cronto-specific actions.", globalPluginReference = "globalCrontoSettings", optional = false)
   private CrontoHandler crontoHandler;
   private static final String CRONTO_HANDLER_PROPERTY = "crontoHandler";

   @ConfigurationValidator
   static void validatePushActivationIsPossible(
      PluginConfiguration conditionConfig, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment
   ) throws ConfigurationException {
      PluginConfiguration crontoHandlerConfig = PluginPropertyValueReader.effectivePluginPropertyValue(conditionConfig, "crontoHandler", env, context);
      Function<String, ConfigurationException> toException = msg -> new PropertyConstraintViolationException(
         "crontoHandler", conditionConfig, env, context, msg
      );
      CrontoPushConfigValidation.validateCrontoHandlerHasPushEnabled(crontoHandlerConfig, env, context, toException);
   }

   public CrontoHandler getCrontoHandler() {
      return this.crontoHandler;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public CrontoPushActivationConditionConfig(CrontoHandler crontoHandler) {
      this.crontoHandler = crontoHandler;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class CrontoPushActivationConditionConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private CrontoHandler crontoHandler;

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

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPushActivationConditionConfig.CrontoPushActivationConditionConfigBuilder crontoHandler(CrontoHandler crontoHandler) {
         this.crontoHandler = crontoHandler;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPushActivationConditionConfig build() {
         return new CrontoPushActivationConditionConfig(this.crontoHandler);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "CrontoPushActivationConditionConfig.CrontoPushActivationConditionConfigBuilder(crontoHandler=" + this.crontoHandler + ")";
      }
   }
}
