package com.airlock.iam.flow.shared.infrastructure.service;

import com.airlock.iam.authentication.api.domain.model.step.IdentityProvidingFlowStep;
import com.airlock.iam.common.infrastructure.delay.ResponseDelayCondition;
import com.airlock.iam.flow.domain.model.session.InternalFlowSession;
import com.airlock.iam.flow.shared.api.domain.model.session.UserSession;
import com.airlock.iam.flow.shared.domain.model.captcha.CaptchaStepError;
import com.airlock.iam.flow.shared.domain.model.session.MultiFlowCapableUserSession;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.core.Response.Status.Family;
import java.util.Optional;

public final class FailureResponseDelayCondition implements ResponseDelayCondition {
   private final Provider<Optional<UserSession>> userSession;

   @Inject
   public FailureResponseDelayCondition(Provider<Optional<UserSession>> userSession) {
      this.userSession = userSession;
   }

   @Override
   public boolean responseDelayRequired(ContainerResponseContext response) {
      return Family.familyOf(response.getStatus()) != Family.SUCCESSFUL && !this.isExcludedError();
   }

   private boolean isExcludedError() {
      return ((Optional)this.userSession.get())
         .filter(MultiFlowCapableUserSession.class::isInstance)
         .map(MultiFlowCapableUserSession.class::cast)
         .flatMap(MultiFlowCapableUserSession::getCurrentFlowSession)
         .flatMap(InternalFlowSession::lastResult)
         .filter(
            res -> res.hasError(CaptchaStepError.CAPTCHA_CHECK_FAILED) || res.hasError(IdentityProvidingFlowStep.IdentityProvidingStepErrors.CONCURRENT_ACCESS)
         )
         .isPresent();
   }
}
