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

import com.airlock.iam.common.application.configuration.credential.BaseSsoTicketRequestAuthenticationConfig;
import com.airlock.iam.common.application.configuration.credential.SsoTicketExtractorConfig;
import com.airlock.iam.common.application.configuration.sso.SsoTicketContextDataExtractorConfig;
import com.airlock.iam.core.application.configuration.AcceptedSsoTicketRepositoryConfig;
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 com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import lombok.NonNull;

@Plugin(description = "Extracts an SSO ticket from a request to authenticate the current session.", displayName = "Admin SSO Ticket Request Authentication")
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Advanced Settings"})
public final class AdminSsoTicketRequestAuthenticationConfig extends BaseSsoTicketRequestAuthenticationConfig {
   public static final String DISPLAY_NAME = "Admin SSO Ticket Request Authentication";
   private SsoTicketExtractorConfig ssoTicketExtractor;
   @StringProperty(description = "The name of the query parameter bearing the SSO ticket to be extracted.", optional = false, exampleValues = "sso")
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String queryParameterName;

   public AdminSsoTicketRequestAuthenticationConfig(
      UserStoreProvider userStore,
      List<UsernameTransformer> usernameTransformers,
      List<String> staticRoles,
      List<String> rolesBlocklist,
      SsoTicketExtractorConfig contextDataExtractorConfig,
      TicketDecoder ticketDecoder,
      @NonNull AcceptedSsoTicketRepositoryConfig acceptedSsoTicketRepository,
      List<SsoTicketContextDataExtractorConfig> contextDataExtractors,
      String usernameKey,
      String providedUsernameKey,
      String rolesKey,
      String queryParameterName
   ) {
      super(
         userStore,
         usernameTransformers,
         staticRoles,
         rolesBlocklist,
         contextDataExtractorConfig,
         ticketDecoder,
         acceptedSsoTicketRepository,
         contextDataExtractors,
         usernameKey,
         providedUsernameKey,
         rolesKey
      );
      if (acceptedSsoTicketRepository == null) {
         throw new NullPointerException("acceptedSsoTicketRepository is marked non-null but is null");
      }

      this.queryParameterName = queryParameterName;
   }

   public String getQueryParameterName() {
      return this.queryParameterName;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class AdminSsoTicketRequestAuthenticationConfigBuilder {
      @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 ArrayList<String> rolesBlocklist;
      @SuppressFBWarnings(justification = "generated code")
      private SsoTicketExtractorConfig contextDataExtractorConfig;
      @SuppressFBWarnings(justification = "generated code")
      private TicketDecoder ticketDecoder;
      @SuppressFBWarnings(justification = "generated code")
      private AcceptedSsoTicketRepositoryConfig acceptedSsoTicketRepository;
      @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")
      private String queryParameterName;

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

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder 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 AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder clearUsernameTransformers() {
         if (this.usernameTransformers != null) {
            this.usernameTransformers.clear();
         }

         return this;
      }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder 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 AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder clearStaticRoles() {
         if (this.staticRoles != null) {
            this.staticRoles.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder rolesBlockListEntry(String rolesBlockListEntry) {
         if (this.rolesBlocklist == null) {
            this.rolesBlocklist = new ArrayList<>();
         }

         this.rolesBlocklist.add(rolesBlockListEntry);
         return this;
      }

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder clearRolesBlocklist() {
         if (this.rolesBlocklist != null) {
            this.rolesBlocklist.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder contextDataExtractorConfig(
         SsoTicketExtractorConfig contextDataExtractorConfig
      ) {
         this.contextDataExtractorConfig = contextDataExtractorConfig;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder acceptedSsoTicketRepository(
         @NonNull AcceptedSsoTicketRepositoryConfig acceptedSsoTicketRepository
      ) {
         if (acceptedSsoTicketRepository == null) {
            throw new NullPointerException("acceptedSsoTicketRepository is marked non-null but is null");
         }

         this.acceptedSsoTicketRepository = acceptedSsoTicketRepository;
         return this;
      }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder 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 AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder clearContextDataExtractors() {
         if (this.contextDataExtractors != null) {
            this.contextDataExtractors.clear();
         }

         return this;
      }

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder queryParameterName(String queryParameterName) {
         this.queryParameterName = queryParameterName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public AdminSsoTicketRequestAuthenticationConfig 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));
         };

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

         return new AdminSsoTicketRequestAuthenticationConfig(
            this.userStore,
            usernameTransformers,
            staticRoles,
            rolesBlocklist,
            this.contextDataExtractorConfig,
            this.ticketDecoder,
            this.acceptedSsoTicketRepository,
            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,
            this.queryParameterName
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "AdminSsoTicketRequestAuthenticationConfig.AdminSsoTicketRequestAuthenticationConfigBuilder(userStore="
            + this.userStore
            + ", usernameTransformers="
            + this.usernameTransformers
            + ", staticRoles="
            + this.staticRoles
            + ", rolesBlocklist="
            + this.rolesBlocklist
            + ", contextDataExtractorConfig="
            + this.contextDataExtractorConfig
            + ", ticketDecoder="
            + this.ticketDecoder
            + ", acceptedSsoTicketRepository="
            + this.acceptedSsoTicketRepository
            + ", contextDataExtractors="
            + this.contextDataExtractors
            + ", usernameKey="
            + this.usernameKey
            + ", providedUsernameKey="
            + this.providedUsernameKey
            + ", rolesKey="
            + this.rolesKey
            + ", queryParameterName="
            + this.queryParameterName
            + ")";
      }
   }
}
