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

import com.airlock.iam.core.domain.model.cronto.CrontoOtp;
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.cronto.CrontoCheckingStep;
import jakarta.inject.Inject;
import java.util.function.Function;

public final class CrontoAuthentication {
   private final FlowProvider flowProvider;

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

   public FlowResult checkOtp(CrontoOtp otp) {
      return this.executeStepMethod(step -> step.checkOtp(otp));
   }

   public FlowResult getCurrentChallenge() {
      return this.executeStepMethod(CrontoCheckingStep::retrieveChallenge);
   }

   public FlowResult pollOnlineValidation(boolean queryOnly) {
      return this.executeStepMethod(step -> step.pollOnlineValidation(queryOnly));
   }

   public FlowResult getPushDeviceChoices() {
      return this.executeStepMethod(CrontoCheckingStep::getPushDeviceChoices);
   }

   public FlowResult selectOfflineAuthentication() {
      return this.executeStepMethod(CrontoCheckingStep::selectOfflineAuthentication);
   }

   public FlowResult selectPushDevice(String id) {
      return this.executeStepMethod(step -> step.selectPushDevice(id));
   }

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