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

import com.airlock.iam.flow.api.application.configuration.selection.FlowConditionConfig;
import com.airlock.iam.flow.api.application.configuration.step.AbstractFlowStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.NonInteractiveStepConfig;
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.types.api.application.configuration.step.StepConfigForAuthenticationFlows;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForAuthorizationFlows;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForPublicSelfServiceFlows;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForSelfServiceFlows;
import com.airlock.iam.oauth2.application.configuration.session.OAuth2SessionRepositoryConfig;
import com.airlock.iam.plugin.api.annotation.config.Groups;
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.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Plugin(description = "Non-interactive step to delete all OAuth 2.0 sessions of a user.", displayName = "OAuth 2.0 Session Reset Step")
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Tags/Guards", "Flow Control"})
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
public final class OAuth2SessionResetStepConfig
   extends AbstractFlowStepConfig
   implements NonInteractiveStepConfig,
   StepConfigForSelfServiceFlows,
   StepConfigForAuthenticationFlows,
   StepConfigForAuthorizationFlows,
   StepConfigForPublicSelfServiceFlows {
   @PluginProperty(description = "OAuth 2.0 session repository.", optional = false)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private OAuth2SessionRepositoryConfig sessionRepository;

   public OAuth2SessionResetStepConfig(
      @Nullable FlowConditionConfig skipCondition,
      @Nullable FlowConditionConfig preCondition,
      boolean requiresActivation,
      List<TagConfig> tagsOnSuccess,
      @Nullable StepIdConfig stepId,
      Map<String, StepIdConfig> onFailureGotos,
      List<ValueMapProviderConfig> customResponseAttributes,
      List<ValueMapProviderConfig> customFailureResponseAttributes,
      OAuth2SessionRepositoryConfig sessionRepository
   ) {
      super(skipCondition, preCondition, requiresActivation, tagsOnSuccess, stepId, onFailureGotos, customResponseAttributes, customFailureResponseAttributes);
      this.sessionRepository = sessionRepository;
   }

   public OAuth2SessionRepositoryConfig getSessionRepository() {
      return this.sessionRepository;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2SessionResetStepConfigBuilder {
      @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 ArrayList<TagConfig> tagsOnSuccess;
      @SuppressFBWarnings(justification = "generated code")
      private StepIdConfig stepId;
      @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 OAuth2SessionRepositoryConfig sessionRepository;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder skipCondition(@Nullable FlowConditionConfig skipCondition) {
         this.skipCondition = skipCondition;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder preCondition(@Nullable FlowConditionConfig preCondition) {
         this.preCondition = preCondition;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder tagOnSuccess(TagConfig tagOnSuccess) {
         if (this.tagsOnSuccess == null) {
            this.tagsOnSuccess = new ArrayList<>();
         }

         this.tagsOnSuccess.add(tagOnSuccess);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder tagsOnSuccess(Collection<? extends TagConfig> tagsOnSuccess) {
         if (tagsOnSuccess == null) {
            throw new NullPointerException("tagsOnSuccess cannot be null");
         }

         if (this.tagsOnSuccess == null) {
            this.tagsOnSuccess = new ArrayList<>();
         }

         this.tagsOnSuccess.addAll(tagsOnSuccess);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder clearTagsOnSuccess() {
         if (this.tagsOnSuccess != null) {
            this.tagsOnSuccess.clear();
         }

         return this;
      }

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

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder sessionRepository(OAuth2SessionRepositoryConfig sessionRepository) {
         this.sessionRepository = sessionRepository;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionResetStepConfig build() {
         return new OAuth2SessionResetStepConfig(
            this.skipCondition, this.preCondition, this.requiresActivation, switch (this.tagsOnSuccess == null ? 0 : this.tagsOnSuccess.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.tagsOnSuccess.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.tagsOnSuccess));
            }, this.stepId, this.onFailureGotos, this.customResponseAttributes, this.customFailureResponseAttributes, this.sessionRepository
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2SessionResetStepConfig.OAuth2SessionResetStepConfigBuilder(skipCondition="
            + this.skipCondition
            + ", preCondition="
            + this.preCondition
            + ", requiresActivation="
            + this.requiresActivation
            + ", tagsOnSuccess="
            + this.tagsOnSuccess
            + ", stepId="
            + this.stepId
            + ", onFailureGotos="
            + this.onFailureGotos
            + ", customResponseAttributes="
            + this.customResponseAttributes
            + ", customFailureResponseAttributes="
            + this.customFailureResponseAttributes
            + ", sessionRepository="
            + this.sessionRepository
            + ")";
      }
   }
}
