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

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.MapifiedValuesBuilder;
import com.airlock.iam.flow.api.domain.model.session.MultiFlowScopedFlowAttribute;
import com.airlock.iam.flow.api.domain.model.step.StepId;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public final class DynamicStepActivationState implements MultiFlowScopedFlowAttribute<DynamicStepActivationState> {
   private static final String STEP_IDS_KEY = "stepIds";
   private final Set<StepId> activatedSteps;

   public DynamicStepActivationState(Set<StepId> activatedSteps) {
      this.activatedSteps = Collections.unmodifiableSet(activatedSteps);
   }

   public DynamicStepActivationState() {
      this(Collections.emptySet());
   }

   public DynamicStepActivationState mergeWith(DynamicStepActivationState newAttribute) {
      return newAttribute;
   }

   @Override
   public MapifiedValues mapify() {
      return MapifiedValuesBuilder.mapifiedValues().put("stepIds", this.activatedSteps.stream().map(StepId::getStepId).toList()).build();
   }

   public static DynamicStepActivationState demapify(MapifiedValues values) {
      return new DynamicStepActivationState(values.demapifySimpleSet("stepIds", stepId -> new StepId((String)stepId)));
   }

   public DynamicStepActivationState withActivatedStep(StepId stepToActivate) {
      Set<StepId> activated = new HashSet<>(this.activatedSteps);
      activated.add(stepToActivate);
      return new DynamicStepActivationState(activated);
   }

   public DynamicStepActivationState withDeactivatedStep(StepId stepToDeactivate) {
      Set<StepId> activated = new HashSet<>(this.activatedSteps);
      activated.remove(stepToDeactivate);
      return new DynamicStepActivationState(activated);
   }

   @SuppressFBWarnings(justification = "generated code")
   public Set<StepId> getActivatedSteps() {
      return this.activatedSteps;
   }
}
