package com.airlock.iam.flow.domain.service;

import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.flow.domain.model.session.FlowSessionStatus;
import com.airlock.iam.flow.domain.model.session.InternalFlowSession;
import com.airlock.iam.flow.domain.model.session.StateMachineHolder;
import com.airlock.iam.flow.domain.model.statemachine.FlowStateMachine;
import com.airlock.iam.flow.domain.model.statemachine.FlowStateMachineFactory;
import com.google.common.base.Preconditions;
import jakarta.inject.Inject;
import jakarta.inject.Provider;

public class FlowSessionStarter {
   private static final ELogger LOG = ELoggerFactory.getLogger(FlowSessionStarter.class);
   private final Provider<FlowStateMachineFactory> stateMachineFactory;
   private final Provider<StateMachineHolder> stateMachineHolder;

   @Inject
   public FlowSessionStarter(Provider<FlowStateMachineFactory> stateMachineFactory, Provider<StateMachineHolder> stateMachineHolder) {
      this.stateMachineFactory = stateMachineFactory;
      this.stateMachineHolder = stateMachineHolder;
   }

   public void startFlowSession(InternalFlowSession flowSession, MultiFlowManager multiFlowManager) {
      Preconditions.checkArgument(
         flowSession.getStatus().isBefore(FlowSessionStatus.STARTED), "Flow session is not expected to have been started at this point."
      );
      FlowStateMachine stateMachine = ((FlowStateMachineFactory)this.stateMachineFactory.get()).createEmptyStateMachine(flowSession, multiFlowManager);
      LOG.debug("Initiating flow...");
      flowSession.start();
      ((StateMachineHolder)this.stateMachineHolder.get()).setStateMachine(() -> stateMachine);
      LOG.debug("Starting state machine...");
      stateMachine.start();
      Preconditions.checkState(!flowSession.getStatus().isBefore(FlowSessionStatus.STARTED), "Flow session is expected to have been started at this point.");
   }
}
