package com.airlock.iam.common.application.configuration.credential;

import com.airlock.iam.common.api.application.configuration.credential.GenericRequestAuthenticationConfig;
import com.airlock.iam.common.application.configuration.sso.PersistentAcceptedSsoTicketRepositoryConfig;
import com.airlock.iam.common.application.configuration.sso.SsoTicketContextDataExtractorConfig;
import com.airlock.iam.core.application.configuration.store.user.UserStoreProvider;
import com.airlock.iam.core.misc.authen.UsernameTransformer;
import com.airlock.iam.core.misc.util.ticket.TicketDecoder;
import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@Plugin(
   description = "Extracts an SSO ticket from a request to authenticate single requests.<p>SSO tickets are not remembered and can be used for multiple requests.</p>",
   displayName = "SSO Ticket Request Authentication"
)
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Advanced Settings"})
public final class SsoTicketRequestAuthenticationConfig extends BaseSsoTicketRequestAuthenticationConfig implements GenericRequestAuthenticationConfig {
   private PersistentAcceptedSsoTicketRepositoryConfig acceptedSsoTicketRepository;

   public SsoTicketRequestAuthenticationConfig(
      UserStoreProvider userStore,
      List<UsernameTransformer> usernameTransformers,
      List<String> staticRoles,
      List<String> rolesBlocklist,
      SsoTicketExtractorConfig ssoTicketExtractor,
      TicketDecoder ticketDecoder,
      List<SsoTicketContextDataExtractorConfig> contextDataExtractors,
      String usernameKey,
      String providedUsernameKey,
      String rolesKey
   ) {
      super(
         userStore,
         usernameTransformers,
         staticRoles,
         rolesBlocklist,
         ssoTicketExtractor,
         ticketDecoder,
         null,
         contextDataExtractors,
         usernameKey,
         providedUsernameKey,
         rolesKey
      );
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class SsoTicketRequestAuthenticationConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private UserStoreProvider userStore;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<UsernameTransformer> usernameTransformers;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<String> staticRoles;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> rolesBlocklist;
      @SuppressFBWarnings(justification = "generated code")
      private SsoTicketExtractorConfig ssoTicketExtractor;
      @SuppressFBWarnings(justification = "generated code")
      private TicketDecoder ticketDecoder;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<SsoTicketContextDataExtractorConfig> contextDataExtractors;
      @SuppressFBWarnings(justification = "generated code")
      private String usernameKey;
      @SuppressFBWarnings(justification = "generated code")
      private String providedUsernameKey;
      @SuppressFBWarnings(justification = "generated code")
      private String rolesKey;

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

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder userStore(UserStoreProvider userStore) {
         this.userStore = userStore;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder usernameTransformer(UsernameTransformer usernameTransformer) {
         if (this.usernameTransformers == null) {
            this.usernameTransformers = new ArrayList<>();
         }

         this.usernameTransformers.add(usernameTransformer);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder usernameTransformers(
         Collection<? extends UsernameTransformer> usernameTransformers
      ) {
         if (usernameTransformers == null) {
            throw new NullPointerException("usernameTransformers cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder clearUsernameTransformers() {
         if (this.usernameTransformers != null) {
            this.usernameTransformers.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder staticRole(String staticRole) {
         if (this.staticRoles == null) {
            this.staticRoles = new ArrayList<>();
         }

         this.staticRoles.add(staticRole);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder staticRoles(Collection<? extends String> staticRoles) {
         if (staticRoles == null) {
            throw new NullPointerException("staticRoles cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder clearStaticRoles() {
         if (this.staticRoles != null) {
            this.staticRoles.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder rolesBlocklist(List<String> rolesBlocklist) {
         this.rolesBlocklist = rolesBlocklist;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder ssoTicketExtractor(SsoTicketExtractorConfig ssoTicketExtractor) {
         this.ssoTicketExtractor = ssoTicketExtractor;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder ticketDecoder(TicketDecoder ticketDecoder) {
         this.ticketDecoder = ticketDecoder;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder contextDataExtractor(
         SsoTicketContextDataExtractorConfig contextDataExtractor
      ) {
         if (this.contextDataExtractors == null) {
            this.contextDataExtractors = new ArrayList<>();
         }

         this.contextDataExtractors.add(contextDataExtractor);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder contextDataExtractors(
         Collection<? extends SsoTicketContextDataExtractorConfig> contextDataExtractors
      ) {
         if (contextDataExtractors == null) {
            throw new NullPointerException("contextDataExtractors cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder clearContextDataExtractors() {
         if (this.contextDataExtractors != null) {
            this.contextDataExtractors.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder usernameKey(String usernameKey) {
         this.usernameKey = usernameKey;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder providedUsernameKey(String providedUsernameKey) {
         this.providedUsernameKey = providedUsernameKey;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder rolesKey(String rolesKey) {
         this.rolesKey = rolesKey;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoTicketRequestAuthenticationConfig build() {
         List usernameTransformers = switch (this.usernameTransformers == null ? 0 : this.usernameTransformers.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.usernameTransformers.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.usernameTransformers));
         };

         List staticRoles = switch (this.staticRoles == null ? 0 : this.staticRoles.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.staticRoles.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.staticRoles));
         };

         return new SsoTicketRequestAuthenticationConfig(
            this.userStore,
            usernameTransformers,
            staticRoles,
            this.rolesBlocklist,
            this.ssoTicketExtractor,
            this.ticketDecoder,
            switch (this.contextDataExtractors == null ? 0 : this.contextDataExtractors.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.contextDataExtractors.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.contextDataExtractors));
            },
            this.usernameKey,
            this.providedUsernameKey,
            this.rolesKey
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "SsoTicketRequestAuthenticationConfig.SsoTicketRequestAuthenticationConfigBuilder(userStore="
            + this.userStore
            + ", usernameTransformers="
            + this.usernameTransformers
            + ", staticRoles="
            + this.staticRoles
            + ", rolesBlocklist="
            + this.rolesBlocklist
            + ", ssoTicketExtractor="
            + this.ssoTicketExtractor
            + ", ticketDecoder="
            + this.ticketDecoder
            + ", contextDataExtractors="
            + this.contextDataExtractors
            + ", usernameKey="
            + this.usernameKey
            + ", providedUsernameKey="
            + this.providedUsernameKey
            + ", rolesKey="
            + this.rolesKey
            + ")";
      }
   }
}
