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

import com.airlock.iam.common.domain.model.credential.CredentialInfo;
import com.airlock.iam.core.misc.impl.authen.credential.TokenCredentialImpl;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
import java.util.function.Supplier;

public class AuthorizationBearerCredentialExtractor implements CredentialExtractor {
   private final BearerTokenExtractor bte = new BearerTokenExtractor();
   private final AuthorizationHeaderExtractor ahe = new AuthorizationHeaderExtractor();

   @Override
   public CredentialInfo extract(HttpServletRequest request) throws CredentialExtractor.CredentialExtractorException {
      return new CredentialInfo(new TokenCredentialImpl(this.getBearerToken(request)));
   }

   public String getBearerToken(HttpServletRequest request) throws CredentialExtractor.CredentialExtractorException {
      Optional<String> authHeader = this.ahe.extract(request);
      Optional<String> bearerToken = this.bte.extract(authHeader.orElseThrow(this.missing("an Authorization header")));
      return bearerToken.orElseThrow(this.missing("a Bearer token"));
   }

   private Supplier<? extends CredentialExtractor.CredentialExtractorException> missing(String description) {
      return () -> new CredentialExtractor.CredentialExtractorException(String.format("The request does not contain %s.", description));
   }
}
