package com.airlock.iam.flow.domain.model.selection.condition;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.flow.api.domain.model.step.FlowCondition;
import com.airlock.iam.flow.application.configuration.selection.condition.LogicalOrFlowConditionConfig;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@LogicForConfig(LogicalOrFlowConditionConfig.class)
public class LogicalOrFlowCondition implements FlowCondition {
   private final List<FlowCondition> innerConditions;

   @Override
   public boolean isFulfilled() {
      return this.innerConditions.stream().reduce(false, (a, b) -> a || b.isFulfilled(), Boolean::logicalOr);
   }

   @Inject
   public LogicalOrFlowCondition(List<FlowCondition> innerConditions) {
      this.innerConditions = innerConditions;
   }

   @Override
   public String displayName() {
      return this.innerConditions.stream().map(FlowCondition::displayName).collect(Collectors.joining(" OR ", "(", ")"));
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class LogicalOrFlowConditionBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<FlowCondition> innerConditions;

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

      @SuppressFBWarnings(justification = "generated code")
      public LogicalOrFlowCondition.LogicalOrFlowConditionBuilder innerCondition(FlowCondition innerCondition) {
         if (this.innerConditions == null) {
            this.innerConditions = new ArrayList<>();
         }

         this.innerConditions.add(innerCondition);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LogicalOrFlowCondition.LogicalOrFlowConditionBuilder innerConditions(Collection<? extends FlowCondition> innerConditions) {
         if (innerConditions == null) {
            throw new NullPointerException("innerConditions cannot be null");
         }

         if (this.innerConditions == null) {
            this.innerConditions = new ArrayList<>();
         }

         this.innerConditions.addAll(innerConditions);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LogicalOrFlowCondition.LogicalOrFlowConditionBuilder clearInnerConditions() {
         if (this.innerConditions != null) {
            this.innerConditions.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LogicalOrFlowCondition build() {
         return new LogicalOrFlowCondition(switch (this.innerConditions == null ? 0 : this.innerConditions.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.innerConditions.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.innerConditions));
         });
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "LogicalOrFlowCondition.LogicalOrFlowConditionBuilder(innerConditions=" + this.innerConditions + ")";
      }
   }
}
