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

import com.airlock.iam.common.api.application.configuration.location.transform.StringTransformerConfig;
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.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
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;

@Plugin(description = "Extracts an SSO ticket from a specified HTTP header contained in the request.", displayName = "SSO Header Ticket Extractor")
@PluginLicenseRestriction(moduleAffiliation = "SSOTickets")
public class SsoHeaderTicketExtractorConfigImpl implements SsoHeaderTicketExtractorConfig {
   @StringProperty(
      description = "The name of the header bearing the value to be extracted.",
      optional = false,
      exampleValues = {"X-Login-OTP", "X-LOGIN-TOKEN"}
   )
   private String headerName;
   @BooleanProperty(
      displayName = "URL-Decode Header Value",
      description = "If enabled, URL-decodes the extracted value using character set UTF8.<p>URL-decoding is applied before the 'String Transformers' run.</p>",
      optional = true,
      defaultValue = "true"
   )
   private boolean urlDecodeValue;
   @PluginListProperty(
      description = "The chain of string transformers that transform the extracted string value to the final extraction result.",
      optional = true,
      minElements = 1
   )
   private List<StringTransformerConfig> stringTransformers;

   public String headerName() {
      return this.headerName;
   }

   @Override
   public boolean urlDecodeValue() {
      return this.urlDecodeValue;
   }

   public List<StringTransformerConfig> stringTransformers() {
      return this.stringTransformers;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public SsoHeaderTicketExtractorConfigImpl(String headerName, boolean urlDecodeValue, List<StringTransformerConfig> stringTransformers) {
      this.headerName = headerName;
      this.urlDecodeValue = urlDecodeValue;
      this.stringTransformers = stringTransformers;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class SsoHeaderTicketExtractorConfigImplBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String headerName;
      @SuppressFBWarnings(justification = "generated code")
      private boolean urlDecodeValue;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<StringTransformerConfig> stringTransformers;

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

      @SuppressFBWarnings(justification = "generated code")
      public SsoHeaderTicketExtractorConfigImpl.SsoHeaderTicketExtractorConfigImplBuilder headerName(String headerName) {
         this.headerName = headerName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoHeaderTicketExtractorConfigImpl.SsoHeaderTicketExtractorConfigImplBuilder urlDecodeValue(boolean urlDecodeValue) {
         this.urlDecodeValue = urlDecodeValue;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoHeaderTicketExtractorConfigImpl.SsoHeaderTicketExtractorConfigImplBuilder stringTransformer(StringTransformerConfig stringTransformer) {
         if (this.stringTransformers == null) {
            this.stringTransformers = new ArrayList<>();
         }

         this.stringTransformers.add(stringTransformer);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoHeaderTicketExtractorConfigImpl.SsoHeaderTicketExtractorConfigImplBuilder stringTransformers(
         Collection<? extends StringTransformerConfig> stringTransformers
      ) {
         if (stringTransformers == null) {
            throw new NullPointerException("stringTransformers cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public SsoHeaderTicketExtractorConfigImpl.SsoHeaderTicketExtractorConfigImplBuilder clearStringTransformers() {
         if (this.stringTransformers != null) {
            this.stringTransformers.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SsoHeaderTicketExtractorConfigImpl build() {
         return new SsoHeaderTicketExtractorConfigImpl(
            this.headerName, this.urlDecodeValue, switch (this.stringTransformers == null ? 0 : this.stringTransformers.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.stringTransformers.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.stringTransformers));
            }
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "SsoHeaderTicketExtractorConfigImpl.SsoHeaderTicketExtractorConfigImplBuilder(headerName="
            + this.headerName
            + ", urlDecodeValue="
            + this.urlDecodeValue
            + ", stringTransformers="
            + this.stringTransformers
            + ")";
      }
   }
}
