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

import com.airlock.iam.flow.api.application.configuration.step.FlowStepConfig;
import com.airlock.iam.flow.api.domain.model.step.FlowStep;
import com.airlock.iam.flow.domain.model.statemachine.FlowState;
import com.airlock.iam.flow.domain.model.step.FlowStepConditionChecker;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Provider;
import lombok.NonNull;

public class StepContext {
   @NonNull
   private final Provider<FlowStep> step;
   @NonNull
   private final FlowStepConfig config;
   @NonNull
   private final Provider<FlowStepConditionChecker> conditionChecker;
   @NonNull
   private final FlowState flowState;

   @SuppressFBWarnings(justification = "generated code")
   StepContext(
      @NonNull Provider<FlowStep> step,
      @NonNull FlowStepConfig config,
      @NonNull Provider<FlowStepConditionChecker> conditionChecker,
      @NonNull FlowState flowState
   ) {
      if (step == null) {
         throw new NullPointerException("step is marked non-null but is null");
      }

      if (config == null) {
         throw new NullPointerException("config is marked non-null but is null");
      }

      if (conditionChecker == null) {
         throw new NullPointerException("conditionChecker is marked non-null but is null");
      }

      if (flowState == null) {
         throw new NullPointerException("flowState is marked non-null but is null");
      }

      this.step = step;
      this.config = config;
      this.conditionChecker = conditionChecker;
      this.flowState = flowState;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static StepContext.StepContextBuilder builder() {
      return new StepContext.StepContextBuilder();
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public Provider<FlowStep> getStep() {
      return this.step;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public FlowStepConfig getConfig() {
      return this.config;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public Provider<FlowStepConditionChecker> getConditionChecker() {
      return this.conditionChecker;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public FlowState getFlowState() {
      return this.flowState;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class StepContextBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Provider<FlowStep> step;
      @SuppressFBWarnings(justification = "generated code")
      private FlowStepConfig config;
      @SuppressFBWarnings(justification = "generated code")
      private Provider<FlowStepConditionChecker> conditionChecker;
      @SuppressFBWarnings(justification = "generated code")
      private FlowState flowState;

      @SuppressFBWarnings(justification = "generated code")
      StepContextBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public StepContext.StepContextBuilder step(@NonNull Provider<FlowStep> step) {
         if (step == null) {
            throw new NullPointerException("step is marked non-null but is null");
         }

         this.step = step;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StepContext.StepContextBuilder config(@NonNull FlowStepConfig config) {
         if (config == null) {
            throw new NullPointerException("config is marked non-null but is null");
         }

         this.config = config;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StepContext.StepContextBuilder conditionChecker(@NonNull Provider<FlowStepConditionChecker> conditionChecker) {
         if (conditionChecker == null) {
            throw new NullPointerException("conditionChecker is marked non-null but is null");
         }

         this.conditionChecker = conditionChecker;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StepContext.StepContextBuilder flowState(@NonNull FlowState flowState) {
         if (flowState == null) {
            throw new NullPointerException("flowState is marked non-null but is null");
         }

         this.flowState = flowState;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StepContext build() {
         return new StepContext(this.step, this.config, this.conditionChecker, this.flowState);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "StepContext.StepContextBuilder(step="
            + this.step
            + ", config="
            + this.config
            + ", conditionChecker="
            + this.conditionChecker
            + ", flowState="
            + this.flowState
            + ")";
      }
   }
}
