package com.airlock.iam.common.domain.model.locale;

import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Locale.LanguageRange;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;

public final class LocalePreferences {
   private static final ELogger LOG = ELoggerFactory.getLogger(LocalePreferences.class);
   private final Locale defaultLocale;
   private final List<Locale> allowedLocales;

   public Locale forAcceptLanguage(String acceptLanguage) {
      if (StringUtils.isNotBlank(acceptLanguage)) {
         try {
            List<LanguageRange> range = LanguageRange.parse(acceptLanguage);
            Locale locale = Locale.lookup(range, this.allowedLocales);
            if (locale != null) {
               return locale;
            }
         } catch (IllegalArgumentException e) {
            LOG.debug("Failed to parse Accept-Language header (" + acceptLanguage + "): " + e.getMessage());
         }
      }

      return this.defaultLocale;
   }

   public Locale forLanguagesInOrder(List<String> tags) {
      List<LanguageRange> ranges = tags.stream().map(LanguageRange::new).collect(Collectors.toList());
      return Optional.ofNullable(Locale.lookup(ranges, this.allowedLocales)).orElse(this.defaultLocale);
   }

   @SuppressFBWarnings("DCN_NULLPOINTER_EXCEPTION")
   public Optional<Locale> forLanguageWithoutDefault(String language) {
      try {
         return Optional.ofNullable(Locale.lookup(List.of(new LanguageRange(language)), this.allowedLocales));
      } catch (IllegalArgumentException | NullPointerException e) {
         return Optional.empty();
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public LocalePreferences(Locale defaultLocale, List<Locale> allowedLocales) {
      this.defaultLocale = defaultLocale;
      this.allowedLocales = allowedLocales;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Locale getDefaultLocale() {
      return this.defaultLocale;
   }

   @SuppressFBWarnings(justification = "generated code")
   public List<Locale> getAllowedLocales() {
      return this.allowedLocales;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof LocalePreferences other)) {
         return false;
      } else {
         Object this$defaultLocale = this.defaultLocale;
         Object other$defaultLocale = other.defaultLocale;
         if (this$defaultLocale == null ? other$defaultLocale == null : this$defaultLocale.equals(other$defaultLocale)) {
            Object this$allowedLocales = this.allowedLocales;
            Object other$allowedLocales = other.allowedLocales;
            return this$allowedLocales == null ? other$allowedLocales == null : this$allowedLocales.equals(other$allowedLocales);
         } else {
            return false;
         }
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      Object $defaultLocale = this.defaultLocale;
      result = result * 59 + ($defaultLocale == null ? 43 : $defaultLocale.hashCode());
      Object $allowedLocales = this.allowedLocales;
      return result * 59 + ($allowedLocales == null ? 43 : $allowedLocales.hashCode());
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "LocalePreferences(defaultLocale=" + this.getDefaultLocale() + ", allowedLocales=" + this.getAllowedLocales() + ")";
   }
}
