package com.airlock.iam.login.application.configuration.targetapp;

import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.IntegerProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.valuereader.IntegerPropertyValueReader;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

@Plugin(description = "Defines the resulting idle timeout and lifetime of a role for a given timeout identifier.")
public class RoleTimeoutRuleConfig {
   @StringProperty(
      description = "Identifier of this rule as stored in the context data. If the identifier matches the one of the user, the configured timeout(s) are added to the role. This value is case-sensitive.",
      optional = false,
      exampleValues = {"LONG", "admin", "office-zurich"}
   )
   private String timeoutIdentifier;
   @IntegerProperty(
      description = "Idle timeout in seconds. If set to 0, the default Airlock Gateway idle timeout is applied.",
      exampleValues = {60, 300, 1800},
      displayName = "Idle Timeout [s]",
      minValue = 0,
      optional = false
   )
   private int idleTimeout;
   private static final String IDLE_TIMEOUT_FIELD = "idleTimeout";
   @IntegerProperty(
      description = "Role lifetime in seconds. If set to 0 or not defined, the default Airlock Gateway lifetime is applied.",
      exampleValues = {600, 1800, 7200},
      displayName = "Lifetime [s]",
      minValue = 0,
      optional = true
   )
   private Integer lifeTime;
   private static final String LIFE_TIME_FIELD = "lifeTime";

   @ConfigurationValidator
   public static void checkProperties(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws ConfigurationException {
      Integer defaultIdleTimeout = IntegerPropertyValueReader.effectiveIntegerConfigValue(config, "idleTimeout", env, context);
      if (defaultIdleTimeout != null) {
         Integer lifeIdleTimeout = IntegerPropertyValueReader.effectiveIntegerConfigValue(config, "lifeTime", env, context);
         if (lifeIdleTimeout != null) {
            if (lifeIdleTimeout < defaultIdleTimeout) {
               throw new PropertyConstraintViolationException(
                  "lifeTime", config, env, context, "The Role Life Time should be equal or greater than the Idle Timeout."
               );
            }
         }
      }
   }

   public String getTimeoutIdentifier() {
      return this.timeoutIdentifier;
   }

   public int getIdleTimeout() {
      return this.idleTimeout;
   }

   public Integer getLifetime() {
      return this.lifeTime;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public RoleTimeoutRuleConfig(String timeoutIdentifier, int idleTimeout, Integer lifeTime) {
      this.timeoutIdentifier = timeoutIdentifier;
      this.idleTimeout = idleTimeout;
      this.lifeTime = lifeTime;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class RoleTimeoutRuleConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String timeoutIdentifier;
      @SuppressFBWarnings(justification = "generated code")
      private int idleTimeout;
      @SuppressFBWarnings(justification = "generated code")
      private Integer lifeTime;

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

      @SuppressFBWarnings(justification = "generated code")
      public RoleTimeoutRuleConfig.RoleTimeoutRuleConfigBuilder timeoutIdentifier(String timeoutIdentifier) {
         this.timeoutIdentifier = timeoutIdentifier;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleTimeoutRuleConfig.RoleTimeoutRuleConfigBuilder idleTimeout(int idleTimeout) {
         this.idleTimeout = idleTimeout;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleTimeoutRuleConfig.RoleTimeoutRuleConfigBuilder lifeTime(Integer lifeTime) {
         this.lifeTime = lifeTime;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleTimeoutRuleConfig build() {
         return new RoleTimeoutRuleConfig(this.timeoutIdentifier, this.idleTimeout, this.lifeTime);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "RoleTimeoutRuleConfig.RoleTimeoutRuleConfigBuilder(timeoutIdentifier="
            + this.timeoutIdentifier
            + ", idleTimeout="
            + this.idleTimeout
            + ", lifeTime="
            + this.lifeTime
            + ")";
      }
   }
}
