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

import com.airlock.iam.common.api.application.configuration.transform.StringTransformerConfig;
import com.airlock.iam.common.api.application.configuration.valueprovider.StringValueProviderConfig;
import com.airlock.iam.common.api.application.configuration.valueprovider.UsernameToPropagateProviderConfig;
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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@Plugin(
   description = "Applies transformations (e.g. uppercase, lowercase, regex) to the output of the configured string value provider.",
   displayName = "Transforming String Value Provider"
)
public class TransformingStringValueProviderConfig implements StringValueProviderConfig, UsernameToPropagateProviderConfig {
   public static final String TRANSFORMING_STRING_VALUE_PROVIDER_DISPLAY_NAME = "Transforming String Value Provider";
   @PluginProperty(description = "String value provider whose output to transform.", optional = false)
   private StringValueProviderConfig valueProvider;
   @PluginListProperty(description = "List of transformations to apply in order on the provided string.", minElements = 1, optional = false)
   private List<StringTransformerConfig> transformations;

   public StringValueProviderConfig getValueProvider() {
      return this.valueProvider;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public TransformingStringValueProviderConfig(StringValueProviderConfig valueProvider, List<StringTransformerConfig> transformations) {
      this.valueProvider = valueProvider;
      this.transformations = transformations;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class TransformingStringValueProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private StringValueProviderConfig valueProvider;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<StringTransformerConfig> transformations;

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

      @SuppressFBWarnings(justification = "generated code")
      public TransformingStringValueProviderConfig.TransformingStringValueProviderConfigBuilder valueProvider(StringValueProviderConfig valueProvider) {
         this.valueProvider = valueProvider;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TransformingStringValueProviderConfig.TransformingStringValueProviderConfigBuilder transformation(StringTransformerConfig transformation) {
         if (this.transformations == null) {
            this.transformations = new ArrayList<>();
         }

         this.transformations.add(transformation);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TransformingStringValueProviderConfig.TransformingStringValueProviderConfigBuilder transformations(
         Collection<? extends StringTransformerConfig> transformations
      ) {
         if (transformations == null) {
            throw new NullPointerException("transformations cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public TransformingStringValueProviderConfig.TransformingStringValueProviderConfigBuilder clearTransformations() {
         if (this.transformations != null) {
            this.transformations.clear();
         }

         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "TransformingStringValueProviderConfig.TransformingStringValueProviderConfigBuilder(valueProvider="
            + this.valueProvider
            + ", transformations="
            + this.transformations
            + ")";
      }
   }
}
