package com.airlock.iam.login.application.configuration.targetapp;

import com.airlock.iam.common.api.application.configuration.role.RoleTransformationConfig;
import com.airlock.iam.flow.shared.application.configuration.valueprovider.RoleProviderConfig;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
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. blacklist, whitelist, Regex) to roles provided by the configured role providers.",
   displayName = "Transforming Role Provider"
)
public class TransformingRoleProviderConfig implements RoleProviderConfig {
   @PluginListProperty(description = "Role providers whose roles to transform.", minElements = 1, optional = false)
   private List<RoleProviderConfig> roleProviders;
   @PluginListProperty(
      description = "Transformations to apply to roles. Note that these transformations are applied in the order in which they are defined in the list.",
      minElements = 1,
      optional = false
   )
   private List<RoleTransformationConfig> roleTransformations;

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

   @SuppressFBWarnings(justification = "generated code")
   public TransformingRoleProviderConfig(List<RoleProviderConfig> roleProviders, List<RoleTransformationConfig> roleTransformations) {
      this.roleProviders = roleProviders;
      this.roleTransformations = roleTransformations;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class TransformingRoleProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<RoleProviderConfig> roleProviders;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<RoleTransformationConfig> roleTransformations;

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

      @SuppressFBWarnings(justification = "generated code")
      public TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder roleProvider(RoleProviderConfig roleProvider) {
         if (this.roleProviders == null) {
            this.roleProviders = new ArrayList<>();
         }

         this.roleProviders.add(roleProvider);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder roleProviders(Collection<? extends RoleProviderConfig> roleProviders) {
         if (roleProviders == null) {
            throw new NullPointerException("roleProviders cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder clearRoleProviders() {
         if (this.roleProviders != null) {
            this.roleProviders.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder roleTransformation(RoleTransformationConfig roleTransformation) {
         if (this.roleTransformations == null) {
            this.roleTransformations = new ArrayList<>();
         }

         this.roleTransformations.add(roleTransformation);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder roleTransformations(
         Collection<? extends RoleTransformationConfig> roleTransformations
      ) {
         if (roleTransformations == null) {
            throw new NullPointerException("roleTransformations cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder clearRoleTransformations() {
         if (this.roleTransformations != null) {
            this.roleTransformations.clear();
         }

         return this;
      }

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

         return new TransformingRoleProviderConfig(roleProviders, switch (this.roleTransformations == null ? 0 : this.roleTransformations.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.roleTransformations.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.roleTransformations));
         });
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "TransformingRoleProviderConfig.TransformingRoleProviderConfigBuilder(roleProviders="
            + this.roleProviders
            + ", roleTransformations="
            + this.roleTransformations
            + ")";
      }
   }
}
