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

import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
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.StringListProperty;
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.PropertyConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.exception.PropertyTypeMismatchException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.commons.lang3.StringUtils;

@Plugin(description = "Configures language settings of the Loginapp.")
@Groups(groupSequence = {"Basic Settings", "Advanced Settings"}, openGroups = "Basic Settings")
public final class LanguageSettings {
   private static final ELogger LOG = ELoggerFactory.getLogger(LanguageSettings.class);
   @StringListProperty(
      description = "A list of values that are accepted as language parameter values. Corresponding Locales must be available. If the requested language is not in the list, the default language is used. The values in the list are <b>not</b> case-sensitive.",
      optional = true,
      exampleElements = {"de", "fr", "en", "en_GB", "de_CH"},
      minElements = 1,
      defaultValue = {"de", "fr", "it", "en"},
      unique = true
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private List<String> validLanguages;
   public static final String VALID_LANGUAGES_FIELD = "validLanguages";
   @StringProperty(
      description = "The default language code used when no or invalid information about the current language is present. A corresponding Locale must be available. The default language must be included in the valid languages.",
      optional = true,
      defaultValue = "en",
      suggestedValues = {"de", "fr", "it", "en", "es"}
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String defaultLanguage;
   public static final String DEFAULT_LANGUAGE_FIELD = "defaultLanguage";
   @StringProperty(
      description = "<p>\n\tLanguage dependent text resources used server-side, e.g., for email, SMS, or push messages, are loaded\n\tfrom property files.<br/>\n\tThis property configures the prefix of these property files.\n</p>\n<p>\n\tExample: If the value of this property is \"strings\", the language dependent files must be\n\t\"<i>strings</i>_de.properties\", \"<i>strings</i>_en.properties\" and so on and the default file\n\tmust be \"<i>strings</i>.properties\".\n</p>\n<p>\n\tNote that text elements used in the Loginapp's web frontend are adapted using the Loginapp Design Kit.\n\tPlease consult the Loginapp Design Kit documentation for further information.\n</p>\n",
      optional = true,
      defaultValue = "strings"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private String resourcesFilePrefix;

   public boolean isLanguageValid(String language) {
      if (StringUtils.isBlank(language)) {
         return false;
      }

      language = language.trim();

      for (String validLanguage : this.validLanguages) {
         if (language.equalsIgnoreCase(validLanguage.trim())) {
            return true;
         }
      }

      return false;
   }

   public Locale getValidLocale(@Nullable String language) {
      try {
         Locale locale = LocaleUtils.toLocale(language);
         if (locale != null && this.isLanguageValid(locale.getLanguage())) {
            return locale;
         }
      } catch (IllegalArgumentException var3) {
      }

      if (language != null) {
         LOG.debug(LogUtil.logSafeQuote(language) + " is not a valid locale. Using default language instead.");
      }

      return LocaleUtils.toLocale(this.defaultLanguage);
   }

   public List<String> getValidLanguages() {
      return this.validLanguages;
   }

   public String getDefaultLanguage() {
      return this.defaultLanguage;
   }

   public String getResourcesFilePrefix() {
      return this.resourcesFilePrefix;
   }

   @ConfigurationValidator
   static void checkLanguageValid(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws PropertyConfigurationException {
      LanguageSettingsValidator.checkLanguageValid(pc, env, context);
   }

   @ConfigurationValidator
   static void checkLocales(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws PropertyConstraintViolationException, PropertyTypeMismatchException {
      LanguageSettingsValidator.checkLocales(pc, env, context, validationEnvironment);
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public LanguageSettings(List<String> validLanguages, String defaultLanguage, String resourcesFilePrefix) {
      this.validLanguages = validLanguages;
      this.defaultLanguage = defaultLanguage;
      this.resourcesFilePrefix = resourcesFilePrefix;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class LanguageSettingsBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private List<String> validLanguages;
      @SuppressFBWarnings(justification = "generated code")
      private String defaultLanguage;
      @SuppressFBWarnings(justification = "generated code")
      private String resourcesFilePrefix;

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

      @SuppressFBWarnings(justification = "generated code")
      public LanguageSettings.LanguageSettingsBuilder validLanguages(List<String> validLanguages) {
         this.validLanguages = validLanguages;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LanguageSettings.LanguageSettingsBuilder defaultLanguage(String defaultLanguage) {
         this.defaultLanguage = defaultLanguage;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LanguageSettings.LanguageSettingsBuilder resourcesFilePrefix(String resourcesFilePrefix) {
         this.resourcesFilePrefix = resourcesFilePrefix;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LanguageSettings build() {
         return new LanguageSettings(this.validLanguages, this.defaultLanguage, this.resourcesFilePrefix);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "LanguageSettings.LanguageSettingsBuilder(validLanguages="
            + this.validLanguages
            + ", defaultLanguage="
            + this.defaultLanguage
            + ", resourcesFilePrefix="
            + this.resourcesFilePrefix
            + ")";
      }
   }
}
