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

import com.airlock.iam.common.api.application.configuration.valueprovider.ValueProviderConfig;
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.PluginMapProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

@Plugin(
   description = "This plugin provides a key-value map where the values are derived from the configured value providers.",
   displayName = "Value Provider Map"
)
public class ValueProviderMapProviderConfig implements ValueMapProviderConfig {
   public static final String VALUE_PROVIDER_MAP_PLUGIN_NAME = "Value Provider Map";
   @PluginMapProperty(description = "The map of value providers from which the values will be derived in order to provide the value map.", optional = false)
   private Map<String, ValueProviderConfig> valueProviders;

   public Map<String, ValueProviderConfig> getValueProviders() {
      return this.valueProviders;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public ValueProviderMapProviderConfig(Map<String, ValueProviderConfig> valueProviders) {
      this.valueProviders = valueProviders;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class ValueProviderMapProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<String> valueProviders$key;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<ValueProviderConfig> valueProviders$value;

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

      @SuppressFBWarnings(justification = "generated code")
      public ValueProviderMapProviderConfig.ValueProviderMapProviderConfigBuilder valueProvider(String valueProviderKey, ValueProviderConfig valueProviderValue) {
         if (this.valueProviders$key == null) {
            this.valueProviders$key = new ArrayList<>();
            this.valueProviders$value = new ArrayList<>();
         }

         this.valueProviders$key.add(valueProviderKey);
         this.valueProviders$value.add(valueProviderValue);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ValueProviderMapProviderConfig.ValueProviderMapProviderConfigBuilder valueProviders(
         Map<? extends String, ? extends ValueProviderConfig> valueProviders
      ) {
         if (valueProviders == null) {
            throw new NullPointerException("valueProviders cannot be null");
         }

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

         for (Entry<? extends String, ? extends ValueProviderConfig> $lombokEntry : valueProviders.entrySet()) {
            this.valueProviders$key.add($lombokEntry.getKey());
            this.valueProviders$value.add($lombokEntry.getValue());
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ValueProviderMapProviderConfig.ValueProviderMapProviderConfigBuilder clearValueProviders() {
         if (this.valueProviders$key != null) {
            this.valueProviders$key.clear();
            this.valueProviders$value.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ValueProviderMapProviderConfig build() {
         return new ValueProviderMapProviderConfig(
            switch (this.valueProviders$key == null ? 0 : this.valueProviders$key.size()) {
               case 0 -> Collections.emptyMap();
               case 1 -> Collections.singletonMap(this.valueProviders$key.get(0), this.valueProviders$value.get(0));
               default -> {
                  Map<String, ValueProviderConfig> valueProviders = new LinkedHashMap<>(
                     this.valueProviders$key.size() < 1073741824
                        ? 1 + this.valueProviders$key.size() + (this.valueProviders$key.size() - 3) / 3
                        : Integer.MAX_VALUE
                  );

                  for (int $i = 0; $i < this.valueProviders$key.size(); $i++) {
                     valueProviders.put(this.valueProviders$key.get($i), this.valueProviders$value.get($i));
                  }

                  yield Collections.unmodifiableMap(valueProviders);
               }
            }
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "ValueProviderMapProviderConfig.ValueProviderMapProviderConfigBuilder(valueProviders$key="
            + this.valueProviders$key
            + ", valueProviders$value="
            + this.valueProviders$value
            + ")";
      }
   }
}
