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

import com.airlock.iam.common.api.application.configuration.valueprovider.DateAndTimeValueProviderConfig;
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.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.valuereader.StringPropertyValueReader;
import com.airlock.iam.plugin.framework.application.configuration.validator.FastDateFormatPatternValidator;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.time.FastDateFormat;

@Plugin(description = "Defines a static date and time value to be provided.", displayName = "Static Date And Time Value Provider")
public final class DateAndTimeStaticValueProviderConfig implements DateAndTimeValueProviderConfig {
   @StringProperty(
      displayName = "Value",
      description = "<p>The date and time value to be provided.</p><p>The string provided by this plugin will be parsed as a date and time value with the format specified in Format.</p>",
      exampleValues = {"2023-02-08T14:27:16+0100", "01.01.1970", "07/30/1947", "Jul 20, 1969 at 20:17 CET"},
      optional = false
   )
   private String value;
   public static final String VALUE_PROPERTY = "value";
   public static final String VALUE_DISPLAY_NAME = "Value";
   @StringProperty(
      displayName = "Format",
      description = "<p>The date and time format used to parse the value provided by Value.</p><p>The format is interpreted as specified in the <tt>java.text.SimpleDateFormat</tt> <a href=\"https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/SimpleDateFormat.html\" target=\"_blank\">documentation</a>.</p>",
      optional = true,
      defaultValue = "yyyy-MM-dd'T'HH:mm:ssZ",
      exampleValues = {"yyyy-MM-dd'T'HH:mm:ssZ", "dd.MM.yyyy", "MM/dd/yyyy", "MMM dd, YYYY 'at' HH:mm z"}
   )
   private String format;
   private static final String FORMAT_PROPERTY = "format";
   private static final String FORMAT_DISPLAY_NAME = "Format";

   @ConfigurationValidator
   public static void validateConfiguredTimezoneAndDateFormat(
      PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment
   ) throws ConfigurationException {
      FastDateFormatPatternValidator.validateFastDateFormatPattern(config, "format", env, context);
      FastDateFormat format = FastDateFormat.getInstance(StringPropertyValueReader.effectiveStringConfigValue(config, "format", env, context));
      FastDateFormatPatternValidator.validateTimeAndDateMatchesFastDateFormat(config, "value", env, context, format);
   }

   public FastDateFormat getFormat() {
      return FastDateFormat.getInstance(this.format);
   }

   public String getValue() {
      return this.value;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public DateAndTimeStaticValueProviderConfig(String value, String format) {
      this.value = value;
      this.format = format;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class DateAndTimeStaticValueProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String value;
      @SuppressFBWarnings(justification = "generated code")
      private String format;

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

      @SuppressFBWarnings(justification = "generated code")
      public DateAndTimeStaticValueProviderConfig.DateAndTimeStaticValueProviderConfigBuilder value(String value) {
         this.value = value;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateAndTimeStaticValueProviderConfig.DateAndTimeStaticValueProviderConfigBuilder format(String format) {
         this.format = format;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateAndTimeStaticValueProviderConfig build() {
         return new DateAndTimeStaticValueProviderConfig(this.value, this.format);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "DateAndTimeStaticValueProviderConfig.DateAndTimeStaticValueProviderConfigBuilder(value=" + this.value + ", format=" + this.format + ")";
      }
   }
}
