package com.airlock.iam.login.application.configuration.location.interpret;

import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.RegexProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;
import java.util.regex.Pattern;

@Plugin(description = "A simple location interpreter to be used to extract a value either from a query parameter or with a regex from the whole location URL.")
public final class SimpleLocationInterpreterConfig implements LocationInterpreterConfig {
   @StringProperty(description = "The default value to be returned if no value could be extracted.", optional = true)
   private String defaultValue;
   @StringProperty(
      description = "Query param from which the value should be extracted.",
      optional = true,
      exampleValues = "lang",
      notCombinableWith = "withUrlRegex",
      mandatoryUnless = "withUrlRegex"
   )
   private String fromQueryParam;
   private static final String FROM_QUERY_PARAM_FIELD = "fromQueryParam";
   @RegexProperty(
      description = "Regex to extract the value from the whole location URL. The value to be extracted (the capturing group) has to be surrounded by parentheses.",
      optional = true,
      exampleValues = {"^(https://ebanking\\.ch/ebanking/).+$", "^.+\\?(.*)$", "/(de|fr|it)/"},
      displayName = "With URL Regex",
      notCombinableWith = "fromQueryParam",
      mandatoryUnless = "fromQueryParam"
   )
   private Pattern withUrlRegex;
   private static final String WITH_URL_REGEX_FIELD = "withUrlRegex";
   @BooleanProperty(description = "If enabled, the extracted value is transformed to lowercase.", optional = true, defaultValue = "false")
   private boolean transformToLowercase;

   @Override
   public Optional<String> getDefaultValue() {
      return Optional.ofNullable(this.defaultValue);
   }

   public String getFromQueryParam() {
      return this.fromQueryParam;
   }

   public Pattern getWithUrlRegex() {
      return this.withUrlRegex;
   }

   public boolean isTransformToLowercase() {
      return this.transformToLowercase;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public SimpleLocationInterpreterConfig(String defaultValue, String fromQueryParam, Pattern withUrlRegex, boolean transformToLowercase) {
      this.defaultValue = defaultValue;
      this.fromQueryParam = fromQueryParam;
      this.withUrlRegex = withUrlRegex;
      this.transformToLowercase = transformToLowercase;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class SimpleLocationInterpreterConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String defaultValue;
      @SuppressFBWarnings(justification = "generated code")
      private String fromQueryParam;
      @SuppressFBWarnings(justification = "generated code")
      private Pattern withUrlRegex;
      @SuppressFBWarnings(justification = "generated code")
      private boolean transformToLowercase;

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

      @SuppressFBWarnings(justification = "generated code")
      public SimpleLocationInterpreterConfig.SimpleLocationInterpreterConfigBuilder defaultValue(String defaultValue) {
         this.defaultValue = defaultValue;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SimpleLocationInterpreterConfig.SimpleLocationInterpreterConfigBuilder fromQueryParam(String fromQueryParam) {
         this.fromQueryParam = fromQueryParam;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SimpleLocationInterpreterConfig.SimpleLocationInterpreterConfigBuilder withUrlRegex(Pattern withUrlRegex) {
         this.withUrlRegex = withUrlRegex;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SimpleLocationInterpreterConfig.SimpleLocationInterpreterConfigBuilder transformToLowercase(boolean transformToLowercase) {
         this.transformToLowercase = transformToLowercase;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SimpleLocationInterpreterConfig build() {
         return new SimpleLocationInterpreterConfig(this.defaultValue, this.fromQueryParam, this.withUrlRegex, this.transformToLowercase);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "SimpleLocationInterpreterConfig.SimpleLocationInterpreterConfigBuilder(defaultValue="
            + this.defaultValue
            + ", fromQueryParam="
            + this.fromQueryParam
            + ", withUrlRegex="
            + this.withUrlRegex
            + ", transformToLowercase="
            + this.transformToLowercase
            + ")";
      }
   }
}
