package com.airlock.iam.oauth2.infrastructure.credential;

import com.airlock.iam.core.application.configuration.waf.AirlockGatewayConfig;
import com.airlock.iam.core.misc.util.crypto.CertUtils;
import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.oauth2.domain.model.credential.OAuth2TokenBindingClientCertificateCredential;
import com.airlock.iam.oauth2.domain.model.credential.OAuth2TokenBindingCredential;
import com.airlock.iam.oauth2.domain.model.credential.OAuth2TokenBindingCredentialExtractor;
import jakarta.servlet.http.HttpServletRequest;
import java.security.cert.CertificateException;
import java.util.Optional;

public class OAuth2TokenBindingClientCertificateCredentialExtractor implements OAuth2TokenBindingCredentialExtractor {
   private static final ELogger LOG = ELoggerFactory.getLogger(OAuth2TokenBindingClientCertificateCredentialExtractor.class);
   private final HttpServletRequest request;
   private final Optional<AirlockGatewayConfig> wafSettings;

   public OAuth2TokenBindingClientCertificateCredentialExtractor(HttpServletRequest request, Optional<AirlockGatewayConfig> wafSettings) {
      this.request = request;
      this.wafSettings = wafSettings;
   }

   @Override
   public Optional<OAuth2TokenBindingCredential> extract() {
      try {
         String airlockEnvCookiePrefix = this.wafSettings.map(AirlockGatewayConfig::getEnvironmentCookiePrefix).orElse(null);
         return Optional.ofNullable(CertUtils.extractClientCertificateFromRequest(this.request, airlockEnvCookiePrefix))
            .map(OAuth2TokenBindingClientCertificateCredential::new);
      } catch (CertificateException e) {
         LOG.warn(EDefaultLogType.GENERIC_LOG_TYPE, "Failed to extract client certificate from request", e);
         return Optional.empty();
      }
   }
}
