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

import com.airlock.iam.common.domain.model.request.ClientIp;
import com.airlock.iam.common.domain.model.request.ClientTlsCertificate;
import com.airlock.iam.common.domain.model.request.RequestId;
import com.airlock.iam.common.domain.model.request.RequestUrl;
import com.airlock.iam.common.domain.model.session.SessionId;
import com.airlock.iam.common.domain.service.request.HttpServletRequestInformationService;
import com.airlock.iam.core.misc.util.crypto.CertUtils;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.servlet.http.HttpServletRequest;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Optional;

public class HttpServletRequestInformationServiceImpl implements HttpServletRequestInformationService {
   private static final ELogger LOG = ELoggerFactory.getLogger(HttpServletRequestInformationServiceImpl.class);
   private final Provider<HttpServletRequest> request;

   @Inject
   public HttpServletRequestInformationServiceImpl(Provider<HttpServletRequest> request) {
      this.request = request;
   }

   @Override
   public Optional<ClientIp> getClientIp() {
      return Optional.of(new ClientIp(((HttpServletRequest)this.request.get()).getRemoteAddr()));
   }

   @Override
   public Optional<RequestId> getRequestId() {
      return Optional.empty();
   }

   @Override
   public Optional<SessionId> getSessionId() {
      return Optional.empty();
   }

   @Override
   public Optional<RequestUrl> getRequestUrl() {
      try {
         return Optional.of(new RequestUrl(((HttpServletRequest)this.request.get()).getRequestURL().toString()));
      } catch (URISyntaxException | MalformedURLException e) {
         LOG.debug("Unable to get request url", e);
         return Optional.empty();
      }
   }

   @Override
   public Optional<ClientTlsCertificate> getMtlsClientCertificate() {
      return Optional.ofNullable(CertUtils.extractClientCertificateFromRequest((HttpServletRequest)this.request.get()))
         .map(ClientTlsCertificate::validClientTlsCertificate);
   }
}
