package com.airlock.iam.login.domain.model.targetapp;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.common.api.domain.model.role.Role;
import com.airlock.iam.common.domain.model.auth.idpropagation.WafCredential;
import com.airlock.iam.common.domain.model.auth.idpropagation.WafCredentialIdleTimeout;
import com.airlock.iam.common.domain.model.auth.idpropagation.WafCredentialLifetime;
import com.airlock.iam.common.domain.model.auth.idpropagation.WafCredentialTimeout;
import com.airlock.iam.common.domain.model.principal.UserPrincipal;
import com.airlock.iam.login.application.configuration.targetapp.UserRoleWafCredentialProviderConfig;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@LogicForConfig(UserRoleWafCredentialProviderConfig.class)
public final class UserRoleWafCredentialProvider implements WafCredentialProvider {
   private final UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration config;
   private final Provider<UserPrincipal> principal;

   @Inject
   public UserRoleWafCredentialProvider(UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration config, Provider<UserPrincipal> principal) {
      this.config = config;
      this.principal = principal;
   }

   @Override
   public List<WafCredential> getCredentials() {
      Set<Role> userRoles = ((UserPrincipal)this.principal.get()).user().getRoles();
      return userRoles.contains(Role.parseRole(this.config.getUserRoleName()))
         ? List.of(
            WafCredential.builder(this.config.getWafCredentialName().orElse(this.config.getUserRoleName()))
               .credentialTimeout(WafCredentialTimeout.wafCredentialTimeout(this.config.getIdleTimeout(), this.config.getLifetime()))
               .build()
         )
         : List.of();
   }

   public static final class UserRoleWafCredentialProviderConfiguration {
      private final String userRoleName;
      private final Optional<String> wafCredentialName;
      private final Optional<WafCredentialLifetime> lifetime;
      private final Optional<WafCredentialIdleTimeout> idleTimeout;

      private UserRoleWafCredentialProviderConfiguration(String userRoleName) {
         this.userRoleName = userRoleName;
         this.wafCredentialName = Optional.empty();
         this.lifetime = Optional.empty();
         this.idleTimeout = Optional.empty();
      }

      public static UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder builder(
         String userRoleName
      ) {
         return new UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration(userRoleName).toBuilder();
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder toBuilder() {
         return new UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder()
            .userRoleName(this.userRoleName)
            .wafCredentialName(this.wafCredentialName)
            .lifetime(this.lifetime)
            .idleTimeout(this.idleTimeout);
      }

      @SuppressFBWarnings(justification = "generated code")
      public String getUserRoleName() {
         return this.userRoleName;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<String> getWafCredentialName() {
         return this.wafCredentialName;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<WafCredentialLifetime> getLifetime() {
         return this.lifetime;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<WafCredentialIdleTimeout> getIdleTimeout() {
         return this.idleTimeout;
      }

      @SuppressFBWarnings(justification = "generated code")
      public UserRoleWafCredentialProviderConfiguration(
         String userRoleName, Optional<String> wafCredentialName, Optional<WafCredentialLifetime> lifetime, Optional<WafCredentialIdleTimeout> idleTimeout
      ) {
         this.userRoleName = userRoleName;
         this.wafCredentialName = wafCredentialName;
         this.lifetime = lifetime;
         this.idleTimeout = idleTimeout;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class UserRoleWafCredentialProviderConfigurationBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private String userRoleName;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<String> wafCredentialName;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<WafCredentialLifetime> lifetime;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<WafCredentialIdleTimeout> idleTimeout;

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

         @SuppressFBWarnings(justification = "generated code")
         public UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder userRoleName(
            String userRoleName
         ) {
            this.userRoleName = userRoleName;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder wafCredentialName(
            Optional<String> wafCredentialName
         ) {
            this.wafCredentialName = wafCredentialName;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder lifetime(
            Optional<WafCredentialLifetime> lifetime
         ) {
            this.lifetime = lifetime;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder idleTimeout(
            Optional<WafCredentialIdleTimeout> idleTimeout
         ) {
            this.idleTimeout = idleTimeout;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration build() {
            return new UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration(
               this.userRoleName, this.wafCredentialName, this.lifetime, this.idleTimeout
            );
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "UserRoleWafCredentialProvider.UserRoleWafCredentialProviderConfiguration.UserRoleWafCredentialProviderConfigurationBuilder(userRoleName="
               + this.userRoleName
               + ", wafCredentialName="
               + this.wafCredentialName
               + ", lifetime="
               + this.lifetime
               + ", idleTimeout="
               + this.idleTimeout
               + ")";
         }
      }
   }
}
