package com.airlock.iam.flow.domain.model.statemachine.spring;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.flow.api.domain.model.step.StepResult;
import com.airlock.iam.flow.domain.model.event.StateMachineFlowEvent;
import com.airlock.iam.flow.domain.model.statemachine.FlowState;
import com.airlock.iam.flow.domain.model.statemachine.runtime.FlowEventFactory;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineEventResult;
import org.springframework.statemachine.StateMachineEventResult.ResultType;
import reactor.core.publisher.Mono;

public final class StateMachineUtil {
   private StateMachineUtil() {
   }

   public static void sendEvent(StepResult stepResult, StateMachine<FlowState, StateMachineFlowEvent> stateMachine) {
      StateMachineEventResult<FlowState, StateMachineFlowEvent> result = (StateMachineEventResult<FlowState, StateMachineFlowEvent>)stateMachine.sendEvent(
            Mono.just(FlowEventFactory.flowEventMessageFor(stepResult))
         )
         .blockLast();
      if (result == null || result.getResultType() == ResultType.DENIED) {
         throw new FailureException("State Machine did not accept event.");
      }
   }
}
