package com.airlock.iam.admin.application.configuration.generic;

import com.airlock.iam.admin.api.application.configuration.token.generic.GenericTokenRepositoryConfig;
import com.airlock.iam.admin.api.domain.model.administrator.CurrentAdministrator;
import com.airlock.iam.admin.api.domain.model.token.generic.GenericTokenAttributeMapping;
import com.airlock.iam.admin.api.domain.model.token.generic.GenericTokenRepository;
import com.airlock.iam.admin.application.service.token.generic.TokenBasedGenericTokenRepository;
import com.airlock.iam.core.misc.persistency.token.TokenDataProvider;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.IntegerProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(description = "Repository that loads tokens from persistence.", displayName = "Token-based Generic Token Repository")
public class TokenBasedGenericTokenRepositoryConfig implements GenericTokenRepositoryConfig {
   @PluginProperty(description = "Data provider to load tokens from persistence.", optional = false)
   private TokenDataProvider tokenDataProvider;
   @IntegerProperty(
      description = "Defines the maximum number of tokens per user.",
      optional = true,
      defaultValue = 1,
      minValue = 1,
      displayName = "Max Tokens Per User",
      exampleValues = {1, 2, 3}
   )
   private Integer maxTokens;
   @PluginProperty(
      description = "Defines the set of supported attributes and optional name mappings.",
      optional = true,
      displayName = "Token Attribute Mapping",
      defaultValue = TokenBasedAttributeMapping.class
   )
   private GenericTokenAttributeMappingConfig attributeMapping;

   @Override
   public GenericTokenRepository getRepository(String tokenType, CurrentAdministrator administrator) {
      return TokenBasedGenericTokenRepository.builder()
         .tokenType(tokenType)
         .maxTokens(this.maxTokens)
         .administrator(administrator)
         .tokenDataProvider(this.tokenDataProvider)
         .build();
   }

   @Override
   public int getMaxTokensPerUser() {
      return this.maxTokens;
   }

   @Override
   public GenericTokenAttributeMapping getAttributeMapping() {
      return this.attributeMapping.getMapping();
   }

   @Override
   public Optional<String> getEnabledProperty() {
      return this.attributeMapping.getMappingForEnabled();
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public TokenBasedGenericTokenRepositoryConfig(TokenDataProvider tokenDataProvider, Integer maxTokens, GenericTokenAttributeMappingConfig attributeMapping) {
      this.tokenDataProvider = tokenDataProvider;
      this.maxTokens = maxTokens;
      this.attributeMapping = attributeMapping;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class TokenBasedGenericTokenRepositoryConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private TokenDataProvider tokenDataProvider;
      @SuppressFBWarnings(justification = "generated code")
      private Integer maxTokens;
      @SuppressFBWarnings(justification = "generated code")
      private GenericTokenAttributeMappingConfig attributeMapping;

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

      @SuppressFBWarnings(justification = "generated code")
      public TokenBasedGenericTokenRepositoryConfig.TokenBasedGenericTokenRepositoryConfigBuilder tokenDataProvider(TokenDataProvider tokenDataProvider) {
         this.tokenDataProvider = tokenDataProvider;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TokenBasedGenericTokenRepositoryConfig.TokenBasedGenericTokenRepositoryConfigBuilder maxTokens(Integer maxTokens) {
         this.maxTokens = maxTokens;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TokenBasedGenericTokenRepositoryConfig.TokenBasedGenericTokenRepositoryConfigBuilder attributeMapping(
         GenericTokenAttributeMappingConfig attributeMapping
      ) {
         this.attributeMapping = attributeMapping;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TokenBasedGenericTokenRepositoryConfig build() {
         return new TokenBasedGenericTokenRepositoryConfig(this.tokenDataProvider, this.maxTokens, this.attributeMapping);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "TokenBasedGenericTokenRepositoryConfig.TokenBasedGenericTokenRepositoryConfigBuilder(tokenDataProvider="
            + this.tokenDataProvider
            + ", maxTokens="
            + this.maxTokens
            + ", attributeMapping="
            + this.attributeMapping
            + ")";
      }
   }
}
