package com.airlock.iam.flow.domain.model.session;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.flow.api.domain.model.flow.FlowId;
import com.airlock.iam.flow.application.configuration.flow.FlowConfigHash;
import com.airlock.iam.flow.types.api.domain.model.session.MultiFlowType;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;
import java.util.Optional;

public final class GenericMultiFlowSession implements MultiFlowSession {
   private final List<FlowConfigHash> configHashes;
   private final MultiFlowType multiFlowType;
   private final FlowId flowId;
   private int numFlowsCompleted;

   public static GenericMultiFlowSession createNewMultiFlowSession(FlowId flowId, MultiFlowType multiFlowType, List<FlowConfigHash> configHashes) {
      return new GenericMultiFlowSession(configHashes, multiFlowType, flowId, 0);
   }

   @Override
   public MultiFlowType getType() {
      return this.multiFlowType;
   }

   @Override
   public void destroy() {
      this.numFlowsCompleted = this.configHashes.size();
   }

   @Override
   public Optional<FlowConfigHash> nextFlowConfigHash() {
      return this.numFlowsCompleted < this.configHashes.size() ? Optional.of(this.configHashes.get(this.numFlowsCompleted)) : Optional.empty();
   }

   @Override
   public void rememberSucceeded(FlowConfigHash hashOfSucceededFlow) {
      if (!this.configHashes.contains(hashOfSucceededFlow)) {
         throw new FailureException("Succeeded flow is not part of current multi-flow");
      }

      if (this.numFlowsCompleted < this.configHashes.size() && this.configHashes.get(this.numFlowsCompleted).equals(hashOfSucceededFlow)) {
         this.numFlowsCompleted++;
      } else {
         throw new FailureException("Unexpected succeeded flow");
      }
   }

   @Override
   public boolean hasNextFlow() {
      return this.numFlowsCompleted < this.configHashes.size();
   }

   @Override
   public FlowId getCurrentFlowId() {
      return this.flowId;
   }

   @Override
   public List<FlowConfigHash> getAllConfigHashes() {
      return this.configHashes;
   }

   @SuppressFBWarnings(justification = "generated code")
   public List<FlowConfigHash> getConfigHashes() {
      return this.configHashes;
   }

   @SuppressFBWarnings(justification = "generated code")
   public MultiFlowType getMultiFlowType() {
      return this.multiFlowType;
   }

   @SuppressFBWarnings(justification = "generated code")
   public FlowId getFlowId() {
      return this.flowId;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int getNumFlowsCompleted() {
      return this.numFlowsCompleted;
   }

   @SuppressFBWarnings(justification = "generated code")
   public GenericMultiFlowSession(List<FlowConfigHash> configHashes, MultiFlowType multiFlowType, FlowId flowId, int numFlowsCompleted) {
      this.configHashes = configHashes;
      this.multiFlowType = multiFlowType;
      this.flowId = flowId;
      this.numFlowsCompleted = numFlowsCompleted;
   }
}
