package com.airlock.iam.flow.shared.application.configuration.valueprovider;

import com.airlock.iam.common.api.application.configuration.valueprovider.StringValueProviderConfig;
import com.airlock.iam.flow.api.application.configuration.valueprovider.ValueMapProviderConfig;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@Plugin(description = "Provides a string which is translated to the current display language.", displayName = "Translated String Provider")
public class TranslationValueProviderConfig implements StringValueProviderConfig {
   @StringProperty(
      description = "<p>Resource key for which the localized strings are defined. The key may contain variables, which are replaced with the provided values before the translation is loaded, e.g. to specify gender-dependent texts, such as salutations.</p><p>The translated string can also contain variables (e.g. <tt>${givenname}</tt>) and supports the same formatting options (including date/time formatting) as are available for Transaction Approval messages.</p>",
      exampleValues = {"general.yes", "salutation.${gender}"},
      optional = false
   )
   private String resourceKey;
   @PluginListProperty(
      description = "List of value map providers that are used to replace the variables in the localized template. The values providers are called in the configured order and their values are added to a map. Later providers can overwrite values from earlier providers. If no value providers are configured, the localized template should not contain any variables, since all of them would be replaced by empty strings.",
      optional = true
   )
   private List<ValueMapProviderConfig> valueProviders;
   @PluginProperty(
      description = "Provides the language that should be used to translate.",
      defaultValue = DisplayLanguageStringProviderConfig.class,
      optional = true
   )
   private StringValueProviderConfig languageProvider;

   public String getResourceKey() {
      return this.resourceKey;
   }

   public List<ValueMapProviderConfig> getValueProviders() {
      return this.valueProviders;
   }

   public StringValueProviderConfig getLanguageProvider() {
      return this.languageProvider;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public TranslationValueProviderConfig(String resourceKey, List<ValueMapProviderConfig> valueProviders, StringValueProviderConfig languageProvider) {
      this.resourceKey = resourceKey;
      this.valueProviders = valueProviders;
      this.languageProvider = languageProvider;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class TranslationValueProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String resourceKey;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<ValueMapProviderConfig> valueProviders;
      @SuppressFBWarnings(justification = "generated code")
      private StringValueProviderConfig languageProvider;

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

      @SuppressFBWarnings(justification = "generated code")
      public TranslationValueProviderConfig.TranslationValueProviderConfigBuilder resourceKey(String resourceKey) {
         this.resourceKey = resourceKey;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TranslationValueProviderConfig.TranslationValueProviderConfigBuilder valueProvider(ValueMapProviderConfig valueProvider) {
         if (this.valueProviders == null) {
            this.valueProviders = new ArrayList<>();
         }

         this.valueProviders.add(valueProvider);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TranslationValueProviderConfig.TranslationValueProviderConfigBuilder valueProviders(Collection<? extends ValueMapProviderConfig> valueProviders) {
         if (valueProviders == null) {
            throw new NullPointerException("valueProviders cannot be null");
         }

         if (this.valueProviders == null) {
            this.valueProviders = new ArrayList<>();
         }

         this.valueProviders.addAll(valueProviders);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TranslationValueProviderConfig.TranslationValueProviderConfigBuilder clearValueProviders() {
         if (this.valueProviders != null) {
            this.valueProviders.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TranslationValueProviderConfig.TranslationValueProviderConfigBuilder languageProvider(StringValueProviderConfig languageProvider) {
         this.languageProvider = languageProvider;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TranslationValueProviderConfig build() {
         return new TranslationValueProviderConfig(this.resourceKey, switch (this.valueProviders == null ? 0 : this.valueProviders.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.valueProviders.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.valueProviders));
         }, this.languageProvider);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "TranslationValueProviderConfig.TranslationValueProviderConfigBuilder(resourceKey="
            + this.resourceKey
            + ", valueProviders="
            + this.valueProviders
            + ", languageProvider="
            + this.languageProvider
            + ")";
      }
   }
}
