package com.airlock.iam.oauth2.infrastructure.service.clientauthentication;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.common.domain.model.request.ClientTlsCertificate;
import com.airlock.iam.oauth2.api.domain.model.clientauthentication.ClientAuthenticationMethod;
import com.airlock.iam.oauth2.api.domain.service.clientauthentication.OAuth2ClientAuthentication;
import com.airlock.iam.oauth2.api.domain.service.clientauthentication.OAuth2ClientAuthenticationParser;
import com.airlock.iam.oauth2.api.domain.service.clientauthentication.OAuth2ClientAuthenticationVerifier;
import com.airlock.iam.oauth2.application.configuration.clientauthentication.OAuth2ClientMTLSAuthenticationConfig;
import com.airlock.iam.oauth2.domain.model.clientauthentication.OAuth2AuthenticationVerifierSource;
import com.airlock.iam.oauth2.domain.model.clientauthentication.OAuth2ClientCertificateAuthenticationPayload;
import com.airlock.iam.oauth2.domain.model.clientauthentication.method.KnownClientAuthenticationMethod;
import com.airlock.iam.oauth2.domain.model.logger.IntegrationLoggerFactory;
import com.airlock.iam.oauth2.domain.service.clientauthentication.certificate.OAuth2ClientCertificateAuthenticationVerifier;
import com.airlock.iam.security.certificate.CertificateStatusChecker;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

@LogicForConfig(OAuth2ClientMTLSAuthenticationConfig.class)
public final class OAuth2ClientMTLSAuthentication implements OAuth2ClientAuthentication<OAuth2ClientCertificateAuthenticationPayload> {
   private final Provider<OAuth2AuthenticationVerifierSource> verifierSource;
   private final Provider<IntegrationLoggerFactory> loggerFactory;
   private final Provider<List<CertificateStatusChecker>> certStatusCheckers;
   private final Provider<Optional<ClientTlsCertificate>> mTlsClientCert;

   @Inject
   public OAuth2ClientMTLSAuthentication(
      Provider<OAuth2AuthenticationVerifierSource> verifierSource,
      Provider<IntegrationLoggerFactory> loggerFactory,
      Provider<List<CertificateStatusChecker>> certStatusCheckers,
      Provider<Optional<ClientTlsCertificate>> mTlsClientCert
   ) {
      this.verifierSource = verifierSource;
      this.loggerFactory = loggerFactory;
      this.certStatusCheckers = certStatusCheckers;
      this.mTlsClientCert = mTlsClientCert;
   }

   @Override
   public List<ClientAuthenticationMethod> supportedAuthenticationMethods() {
      return List.of(KnownClientAuthenticationMethod.MTLS_CERTIFICATE);
   }

   @Override
   public OAuth2ClientAuthenticationParser<OAuth2ClientCertificateAuthenticationPayload> authenticationParser() {
      return new OAuth2ClientMTLSAuthenticationParser(
         (Optional<ClientTlsCertificate>)this.mTlsClientCert.get(),
         ((IntegrationLoggerFactory)this.loggerFactory.get()).create(OAuth2ClientMTLSAuthenticationParser.class)
      );
   }

   @Override
   public OAuth2ClientAuthenticationVerifier<OAuth2ClientCertificateAuthenticationPayload> verifier() {
      return OAuth2ClientCertificateAuthenticationVerifier.builder()
         .verifierSource((OAuth2AuthenticationVerifierSource)this.verifierSource.get())
         .certStatusCheckers((Collection<CertificateStatusChecker>)this.certStatusCheckers.get())
         .logger(((IntegrationLoggerFactory)this.loggerFactory.get()).create(OAuth2ClientCertificateAuthenticationVerifier.class))
         .build();
   }
}
