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

import com.airlock.iam.core.misc.util.LanguageUtils;
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 com.airlock.iam.plugin.api.valuereader.StringListPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.StringPropertyValueReader;
import java.util.List;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.commons.lang3.Strings;

public final class LanguageSettingsValidator {
   public static void checkLanguageValid(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context) throws PropertyConfigurationException {
      String defaultLang = StringPropertyValueReader.effectiveStringConfigValue(pc, "defaultLanguage", env, context);
      List<String> validLanguages = StringListPropertyValueReader.effectiveStringListConfigValue(pc, "validLanguages", env, context);
      validLanguages.stream()
         .filter(lang -> Strings.CI.equals(lang, defaultLang))
         .findAny()
         .orElseThrow(
            () -> new PropertyConstraintViolationException("validLanguages", pc, env, context, "The default language is not included in the valid languages.")
         );
   }

   public static void checkLocales(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws PropertyConstraintViolationException, PropertyTypeMismatchException {
      if (validationEnvironment == Environment.CURRENT_VM) {
         for (String currentLang : StringListPropertyValueReader.effectiveStringListConfigValue(pc, "validLanguages", env, context)) {
            ensureLocaleExists(pc, env, context, validationEnvironment, "validLanguages", currentLang);
         }
      }
   }

   public static void ensureLocaleExists(
      PluginConfiguration pc,
      ConfigurationEnvironment env,
      ConfigurationContext context,
      Environment validationEnvironment,
      String propertyName,
      String language
   ) throws PropertyConstraintViolationException {
      if (validationEnvironment == Environment.CURRENT_VM && !LocaleUtils.isAvailableLocale(LanguageUtils.getLocale(language))) {
         throw new PropertyConstraintViolationException(propertyName, pc, env, context, "No locale available for language: " + language);
      }
   }

   private LanguageSettingsValidator() {
   }
}
