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

import com.airlock.iam.admin.api.domain.model.user.AuthenticationMethods;
import com.airlock.iam.admin.domain.model.token.TokenController;
import com.airlock.iam.core.misc.persistency.token.TokenDataProvider;
import com.airlock.iam.oauth2.application.configuration.consentstorage.OAuth2ConsentRepositoryConfig;
import com.airlock.iam.oauth2.application.configuration.session.OAuth2SessionRepositoryConfig;
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.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(description = "Token controller to manage a user's OAuth 2.0 Tokens.", displayName = "OAuth 2.0 Token Controller")
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
public class OAuth2TokenController implements TokenController {
   @TokenController.TokenControllerId
   public static final String ID = "OAUTH2";
   @PluginProperty(
      description = "Token Data Provider responsible for persisting OAuth 2.0 Tokens.",
      globalPluginReference = "globalTokenDataProvider",
      optional = false
   )
   private TokenDataProvider tokenDataProvider;
   @PluginProperty(description = "OAuth 2.0 session repository repository config.", optional = false)
   private OAuth2SessionRepositoryConfig sessionRepository;
   @PluginProperty(displayName = "OAuth 2.0 Consent Repository", description = "Configures a repository storing OAuth 2.0 consent decisions.", optional = true)
   private OAuth2ConsentRepositoryConfig consentRepository;

   @Override
   public AuthenticationMethods.AuthenticationMethodId getConfiguredId() {
      return AuthenticationMethods.AuthenticationMethodId.authMethodId("OAUTH2");
   }

   @Override
   public String getTokenControllerId() {
      return "OAUTH2";
   }

   public TokenDataProvider tokenDataProvider() {
      return this.tokenDataProvider;
   }

   public OAuth2SessionRepositoryConfig sessionRepository() {
      return this.sessionRepository;
   }

   public Optional<OAuth2ConsentRepositoryConfig> consentRepository() {
      return Optional.ofNullable(this.consentRepository);
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2TokenController(
      TokenDataProvider tokenDataProvider, OAuth2SessionRepositoryConfig sessionRepository, OAuth2ConsentRepositoryConfig consentRepository
   ) {
      this.tokenDataProvider = tokenDataProvider;
      this.sessionRepository = sessionRepository;
      this.consentRepository = consentRepository;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2TokenControllerBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private TokenDataProvider tokenDataProvider;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2SessionRepositoryConfig sessionRepository;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ConsentRepositoryConfig consentRepository;

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2TokenController.OAuth2TokenControllerBuilder sessionRepository(OAuth2SessionRepositoryConfig sessionRepository) {
         this.sessionRepository = sessionRepository;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2TokenController.OAuth2TokenControllerBuilder consentRepository(OAuth2ConsentRepositoryConfig consentRepository) {
         this.consentRepository = consentRepository;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2TokenController build() {
         return new OAuth2TokenController(this.tokenDataProvider, this.sessionRepository, this.consentRepository);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2TokenController.OAuth2TokenControllerBuilder(tokenDataProvider="
            + this.tokenDataProvider
            + ", sessionRepository="
            + this.sessionRepository
            + ", consentRepository="
            + this.consentRepository
            + ")";
      }
   }
}
