package com.airlock.iam.flow.shared.application.service.fido;

import com.airlock.iam.factor.domain.model.fido.FidoAuthenticatorUnverifiedAssertionResponse;
import com.airlock.iam.factor.domain.model.fido.FidoClientFailure;
import com.airlock.iam.flow.api.domain.model.flow.FlowResult;
import com.airlock.iam.flow.api.domain.model.step.StepResult;
import com.airlock.iam.flow.domain.model.flow.FlowProvider;
import com.airlock.iam.flow.shared.domain.model.fido.FidoCheckingStep;
import com.airlock.iam.flow.shared.domain.model.fido.FidoCheckingStepWithRetrieve;
import jakarta.inject.Inject;
import java.util.function.Function;

public final class FidoCheck {
   private final FlowProvider flowProvider;

   @Inject
   public FidoCheck(FlowProvider flowProvider) {
      this.flowProvider = flowProvider;
   }

   public FlowResult retrieveAuthenticationChallenge() {
      return this.flowProvider
         .getCurrentOrStartNew()
         .execute(FidoCheckingStepWithRetrieve::retrieveAuthenticationChallenge, FidoCheckingStepWithRetrieve.class);
   }

   public FlowResult verify(FidoAuthenticatorUnverifiedAssertionResponse authenticatorResponse) {
      return this.executeStepMethod(step -> step.verify(authenticatorResponse));
   }

   public FlowResult reportClientFailure(FidoClientFailure failure) {
      return this.executeStepMethod(step -> step.reportClientFailure(failure));
   }

   private FlowResult executeStepMethod(Function<FidoCheckingStep, StepResult> stepMethod) {
      return this.flowProvider.getCurrentOrStartNew().execute(stepMethod, FidoCheckingStep.class);
   }
}
