package com.airlock.iam.oauth2.infrastructure.exception.v3;

import com.airlock.iam.base.api.infrastructure.uri.ExternalUriInfo;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.core.misc.util.ExceptionUtils;
import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.ExceptionMapper;
import java.util.Optional;
import java.util.stream.Collectors;

@jakarta.ws.rs.ext.Provider
public final class OAuth2V3ValidationExceptionMapper implements ExceptionMapper<ValidationException> {
   private static final ELogger LOG = ELoggerFactory.getLogger(OAuth2V3ValidationExceptionMapper.class);
   private final Provider<ExternalUriInfo> uriInfo;

   @Inject
   public OAuth2V3ValidationExceptionMapper(Provider<ExternalUriInfo> uriInfo) {
      this.uriInfo = uriInfo;
   }

   public Response toResponse(ValidationException exception) {
      LOG.info(
         EDefaultLogType.GENERIC_LOG_TYPE,
         "Validation error while handling OAuth 2.0 request "
            + LogUtil.logSafeQuote(((ExternalUriInfo)this.uriInfo.get()).getAbsolutePath())
            + this.getDetails(exception)
      );
      return Response.status(Status.NOT_FOUND).build();
   }

   private String getDetails(ValidationException exception) {
      return exception instanceof ConstraintViolationException cve
         ? ": " + cve.getConstraintViolations().stream().<CharSequence>map(ConstraintViolation::getMessage).collect(Collectors.joining("; "))
         : Optional.ofNullable(ExceptionUtils.extractCause(exception)).map(message -> ": " + message).orElse("");
   }
}
