package com.airlock.iam.oauth2.application.configuration;

import com.airlock.iam.flow.api.application.configuration.dynamicactivation.DynamicStepActivationConfig;
import com.airlock.iam.flow.api.application.configuration.redflag.RedFlagConfig;
import com.airlock.iam.flow.api.application.configuration.selection.FlowConditionConfig;
import com.airlock.iam.flow.api.application.configuration.step.AbstractInteractiveFlowStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.InteractiveGotoTargetConfig;
import com.airlock.iam.flow.api.application.configuration.step.RedFlagHandlingStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.StepIdConfig;
import com.airlock.iam.flow.api.application.configuration.tag.TagConfig;
import com.airlock.iam.flow.api.application.configuration.valueprovider.ValueMapProviderConfig;
import com.airlock.iam.flow.application.configuration.redflag.RedFlagConfigImpl;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForAuthenticationFlows;
import com.airlock.iam.oauth2.domain.model.provider.OAuth2ConsentStep;
import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.NextActions;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginLicenseRestriction;
import com.airlock.iam.plugin.framework.application.service.builder.plugin.PluginPropertyBuilderInitializer;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Plugin(
   description = "The OAuth 2.0 consent step. Depending on the configured consent in the grant settings this step will handle the consent. If no consent is configured, the step is non-interactive and will implicitly allow all scopes that were not restricted. ",
   displayName = "OAuth 2.0 Consent Step"
)
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
@Groups(groupSequence = {"Flow Control", "Tags/Guards"})
@NextActions(OAuth2ConsentStep.OAuth2ConsentStepActions.class)
public class OAuth2ConsentStepConfig extends AbstractInteractiveFlowStepConfig implements RedFlagHandlingStepConfig, StepConfigForAuthenticationFlows {
   public static final String OAUTH2_CONSENT_STEP_DISPLAY_NAME = "OAuth 2.0 Consent Step";
   private static final RedFlagConfig CONSENT_REQUIRED_RED_FLAG = ((RedFlagConfigImpl.RedFlagConfigImplBuilder)PluginPropertyBuilderInitializer.builder(
         RedFlagConfigImpl.RedFlagConfigImplBuilder.class
      ))
      .name("OAUTH2_CONSENT_REQUIRED")
      .build();
   private FlowConditionConfig skipCondition;
   private boolean requiresActivation;

   public OAuth2ConsentStepConfig(
      FlowConditionConfig skipCondition,
      FlowConditionConfig preCondition,
      boolean requiresActivation,
      List<TagConfig> tagsOnSuccess,
      @Nullable StepIdConfig stepId,
      List<InteractiveGotoTargetConfig> interactiveGotoTargets,
      List<DynamicStepActivationConfig> dynamicStepActivations,
      Map<String, StepIdConfig> onFailureGotos,
      List<ValueMapProviderConfig> customResponseAttributes,
      List<ValueMapProviderConfig> customFailureResponseAttributes,
      RedFlagConfig redFlagToTakeDown
   ) {
      super(
         skipCondition,
         preCondition,
         requiresActivation,
         tagsOnSuccess,
         stepId,
         interactiveGotoTargets,
         dynamicStepActivations,
         onFailureGotos,
         customResponseAttributes,
         customFailureResponseAttributes
      );
   }

   @Override
   public RedFlagConfig getRedFlag() {
      return CONSENT_REQUIRED_RED_FLAG;
   }

   @Override
   public Optional<FlowConditionConfig> getSkipCondition() {
      return Optional.empty();
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2ConsentStepConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private FlowConditionConfig skipCondition;
      @SuppressFBWarnings(justification = "generated code")
      private FlowConditionConfig preCondition;
      @SuppressFBWarnings(justification = "generated code")
      private boolean requiresActivation;
      @SuppressFBWarnings(justification = "generated code")
      private List<TagConfig> tagsOnSuccess;
      @SuppressFBWarnings(justification = "generated code")
      private StepIdConfig stepId;
      @SuppressFBWarnings(justification = "generated code")
      private List<InteractiveGotoTargetConfig> interactiveGotoTargets;
      @SuppressFBWarnings(justification = "generated code")
      private List<DynamicStepActivationConfig> dynamicStepActivations;
      @SuppressFBWarnings(justification = "generated code")
      private Map<String, StepIdConfig> onFailureGotos;
      @SuppressFBWarnings(justification = "generated code")
      private List<ValueMapProviderConfig> customResponseAttributes;
      @SuppressFBWarnings(justification = "generated code")
      private List<ValueMapProviderConfig> customFailureResponseAttributes;
      @SuppressFBWarnings(justification = "generated code")
      private RedFlagConfig redFlagToTakeDown;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder skipCondition(FlowConditionConfig skipCondition) {
         this.skipCondition = skipCondition;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder preCondition(FlowConditionConfig preCondition) {
         this.preCondition = preCondition;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder requiresActivation(boolean requiresActivation) {
         this.requiresActivation = requiresActivation;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder tagsOnSuccess(List<TagConfig> tagsOnSuccess) {
         this.tagsOnSuccess = tagsOnSuccess;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder stepId(@Nullable StepIdConfig stepId) {
         this.stepId = stepId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder interactiveGotoTargets(List<InteractiveGotoTargetConfig> interactiveGotoTargets) {
         this.interactiveGotoTargets = interactiveGotoTargets;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder dynamicStepActivations(List<DynamicStepActivationConfig> dynamicStepActivations) {
         this.dynamicStepActivations = dynamicStepActivations;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder onFailureGotos(Map<String, StepIdConfig> onFailureGotos) {
         this.onFailureGotos = onFailureGotos;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder customResponseAttributes(List<ValueMapProviderConfig> customResponseAttributes) {
         this.customResponseAttributes = customResponseAttributes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder customFailureResponseAttributes(
         List<ValueMapProviderConfig> customFailureResponseAttributes
      ) {
         this.customFailureResponseAttributes = customFailureResponseAttributes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder redFlagToTakeDown(RedFlagConfig redFlagToTakeDown) {
         this.redFlagToTakeDown = redFlagToTakeDown;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ConsentStepConfig build() {
         return new OAuth2ConsentStepConfig(
            this.skipCondition,
            this.preCondition,
            this.requiresActivation,
            this.tagsOnSuccess,
            this.stepId,
            this.interactiveGotoTargets,
            this.dynamicStepActivations,
            this.onFailureGotos,
            this.customResponseAttributes,
            this.customFailureResponseAttributes,
            this.redFlagToTakeDown
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2ConsentStepConfig.OAuth2ConsentStepConfigBuilder(skipCondition="
            + this.skipCondition
            + ", preCondition="
            + this.preCondition
            + ", requiresActivation="
            + this.requiresActivation
            + ", tagsOnSuccess="
            + this.tagsOnSuccess
            + ", stepId="
            + this.stepId
            + ", interactiveGotoTargets="
            + this.interactiveGotoTargets
            + ", dynamicStepActivations="
            + this.dynamicStepActivations
            + ", onFailureGotos="
            + this.onFailureGotos
            + ", customResponseAttributes="
            + this.customResponseAttributes
            + ", customFailureResponseAttributes="
            + this.customFailureResponseAttributes
            + ", redFlagToTakeDown="
            + this.redFlagToTakeDown
            + ")";
      }
   }
}
