package com.airlock.iam.oauth2.application.configuration.scope;

import com.airlock.iam.oauth2.application.configuration.OAuth2ScopeTranslatorSpec;
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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Plugin(
   description = "Plugin to transform OAuth 2.0 scopes to human-readable versions. These translations are used on multiple pages, where\nend-users interact with scopes, e.g. on the consent or self-service session management page.\nScope translations are only used in the Loginapp and have no effect in the Adminapp.",
   displayName = "OAuth 2.0 Scope Translator"
)
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
public class OAuth2ScopeTranslator implements OAuth2ScopeTranslatorSpec {
   @PluginListProperty(
      description = "List of translation rules for OAuth 2.0 scopes.\nIf more than one scope translation matches a scope name, the first translation found in the list will be used.",
      optional = false
   )
   private List<OAuth2ScopeTranslationEntry> scopeTranslations;

   @Override
   public Optional<String> getPropertyKey(String scope) {
      for (OAuth2ScopeTranslationEntry translation : this.scopeTranslations) {
         if (translation.getScopePattern().matcher(scope).matches()) {
            return Optional.of(translation.getTranslationKey());
         }
      }

      return Optional.empty();
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2ScopeTranslator(List<OAuth2ScopeTranslationEntry> scopeTranslations) {
      this.scopeTranslations = scopeTranslations;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2ScopeTranslatorBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<OAuth2ScopeTranslationEntry> scopeTranslations;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ScopeTranslator.OAuth2ScopeTranslatorBuilder scopeTranslation(OAuth2ScopeTranslationEntry scopeTranslation) {
         if (this.scopeTranslations == null) {
            this.scopeTranslations = new ArrayList<>();
         }

         this.scopeTranslations.add(scopeTranslation);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ScopeTranslator.OAuth2ScopeTranslatorBuilder scopeTranslations(Collection<? extends OAuth2ScopeTranslationEntry> scopeTranslations) {
         if (scopeTranslations == null) {
            throw new NullPointerException("scopeTranslations cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ScopeTranslator.OAuth2ScopeTranslatorBuilder clearScopeTranslations() {
         if (this.scopeTranslations != null) {
            this.scopeTranslations.clear();
         }

         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2ScopeTranslator.OAuth2ScopeTranslatorBuilder(scopeTranslations=" + this.scopeTranslations + ")";
      }
   }
}
