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

import com.airlock.iam.factor.domain.model.airlock2fa.activation.Airlock2FAActivationCode;
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.airlock2fa.Airlock2FAActivationFlowBindingStep;
import com.airlock.iam.flow.shared.domain.model.airlock2fa.Airlock2FAActivationStatusStep;
import com.airlock.iam.flow.shared.domain.model.airlock2fa.Airlock2FAActivationStep;
import jakarta.inject.Inject;
import java.util.function.Function;

public final class Airlock2FAActivation {
   private final FlowProvider flow;

   @Inject
   public Airlock2FAActivation(FlowProvider flow) {
      this.flow = flow;
   }

   public FlowResult retrieveActivationChallenge() {
      return this.executeActivationStepMethod(Airlock2FAActivationStep::retrieveActivationChallenge);
   }

   public FlowResult pollActivationResult(boolean queryOnly) {
      return this.executeActivationStatusStepMethod(step -> step.pollActivationResult(queryOnly));
   }

   public FlowResult getBindingToken(Airlock2FAActivationCode activationCode) {
      return this.executeActivationFlowBindingStepMethod(step -> step.getBindingToken(activationCode));
   }

   private FlowResult executeActivationStepMethod(Function<Airlock2FAActivationStep, StepResult> stepMethod) {
      return this.flow.getCurrentOrStartNew().execute(stepMethod, Airlock2FAActivationStep.class);
   }

   private FlowResult executeActivationStatusStepMethod(Function<Airlock2FAActivationStatusStep, StepResult> stepMethod) {
      return this.flow.getCurrentOrStartNew().execute(stepMethod, Airlock2FAActivationStatusStep.class);
   }

   private FlowResult executeActivationFlowBindingStepMethod(Function<Airlock2FAActivationFlowBindingStep, StepResult> stepMethod) {
      return this.flow.getCurrentOrStartNew().execute(stepMethod, Airlock2FAActivationFlowBindingStep.class);
   }
}
