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

import com.airlock.iam.flow.api.application.configuration.valueprovider.ValueMapProviderConfig;
import com.airlock.iam.flow.shared.api.application.configuration.message.Airlock2FAMessageProviderConfig;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginLicenseRestriction;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
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 = "Generic message provider for Airlock 2FA.", displayName = "Airlock 2FA Message Provider")
@PluginLicenseRestriction(moduleAffiliation = "Airlock2FA")
public class GenericAirlock2FAMessageProviderConfig implements Airlock2FAMessageProviderConfig {
   public static final String DESCRIPTION_OF_VARIABLES_AND_FORMATTING = "Variables are replaced with the corresponding values provided by the \"Value Providers\". For more information about formatting, consult the customer documentation.";
   @StringProperty(
      description = "<p>This key identifies the message template that is used to generate the message title. The title is displayed in the Airlock 2FA mobile app after the word \"Approve\", e.g. \"Login\" or \"Password Reset\".</p><p>It is displayed for One-Touch, Online QR Code and Usernameless QR Code factors.</p><p>It is ignored for Offline QR Code. Because of technical limitations, the title of Offline QR Codes is always the default title from Futurae.<p><p>The string resource key itself may also contain variables, e.g. 'airlock2fa.message.${type}.title'. Variables are replaced with the corresponding values provided by the \"Value Providers\". For more information about formatting, consult the customer documentation.</p>",
      exampleValues = {
            "self-service.user-data-edit.approval.airlock-2fa.title", "password-reset.factors.airlock-2fa.title", "airlock2fa.one-touch.authentication-title"
      },
      optional = false
   )
   private String titleTranslationKey;
   @PluginListProperty(
      description = "Configures the various contextual information that will be displayed on the Airlock 2FA app of a user when a message approval is started. Note that for readability reasons it is not recommended to provide more than three entries of such contextual information.<p>These information items are displayed for One-Touch, Online QR Code, Offline QR Code and Usernameless QR Code factors.</p>",
      optional = true
   )
   private List<Airlock2FAInformationItemConfig> informationItems;
   @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;

   public String getTitleTranslationKey() {
      return this.titleTranslationKey;
   }

   public List<Airlock2FAInformationItemConfig> getInformationItems() {
      return this.informationItems;
   }

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

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

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

   @SuppressFBWarnings(justification = "generated code")
   public GenericAirlock2FAMessageProviderConfig(
      String titleTranslationKey, List<Airlock2FAInformationItemConfig> informationItems, List<ValueMapProviderConfig> valueProviders
   ) {
      this.titleTranslationKey = titleTranslationKey;
      this.informationItems = informationItems;
      this.valueProviders = valueProviders;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class GenericAirlock2FAMessageProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String titleTranslationKey;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<Airlock2FAInformationItemConfig> informationItems;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<ValueMapProviderConfig> valueProviders;

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

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder titleTranslationKey(String titleTranslationKey) {
         this.titleTranslationKey = titleTranslationKey;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder informationItem(
         Airlock2FAInformationItemConfig informationItem
      ) {
         if (this.informationItems == null) {
            this.informationItems = new ArrayList<>();
         }

         this.informationItems.add(informationItem);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder informationItems(
         Collection<? extends Airlock2FAInformationItemConfig> informationItems
      ) {
         if (informationItems == null) {
            throw new NullPointerException("informationItems cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder clearInformationItems() {
         if (this.informationItems != null) {
            this.informationItems.clear();
         }

         return this;
      }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder 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 GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder clearValueProviders() {
         if (this.valueProviders != null) {
            this.valueProviders.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderConfig build() {
         List informationItems = switch (this.informationItems == null ? 0 : this.informationItems.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.informationItems.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.informationItems));
         };

         return new GenericAirlock2FAMessageProviderConfig(
            this.titleTranslationKey, informationItems, 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));
            }
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "GenericAirlock2FAMessageProviderConfig.GenericAirlock2FAMessageProviderConfigBuilder(titleTranslationKey="
            + this.titleTranslationKey
            + ", informationItems="
            + this.informationItems
            + ", valueProviders="
            + this.valueProviders
            + ")";
      }
   }
}
