package com.airlock.iam.oauth2.infrastructure.discovery.compatibility;

import com.google.common.collect.Lists;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public final class OpenIDConnectCompatibilityResult {
   public static final String MESSAGE_DELIMITER = "\n* ";
   public static final String WARNINGS_MESSAGE_PREFIX = "Warnings:\n* ";
   public static final String INCOMPATIBILITIES_MESSAGE_PREFIX = "Found incompatibilities:\n* ";
   public static final OpenIDConnectCompatibilityResult SUCCESS = new OpenIDConnectCompatibilityResult();
   private final List<OpenIDConnectIncompatibility> incompatibilities;
   private final List<OpenIDConnectCompatibilityWarning> warnings;

   public static OpenIDConnectCompatibilityResult withIncompatibility(OpenIDConnectIncompatibility incompatibility) {
      return new OpenIDConnectCompatibilityResult(Lists.newArrayList(new OpenIDConnectIncompatibility[]{incompatibility}), Lists.newArrayList());
   }

   public static OpenIDConnectCompatibilityResult withWarning(OpenIDConnectCompatibilityWarning warning) {
      return new OpenIDConnectCompatibilityResult(Lists.newArrayList(), Lists.newArrayList(new OpenIDConnectCompatibilityWarning[]{warning}));
   }

   private OpenIDConnectCompatibilityResult() {
      this.incompatibilities = Lists.newArrayList();
      this.warnings = Lists.newArrayList();
   }

   public Optional<String> getIncompatibilityMessage() {
      return this.incompatibilities.isEmpty()
         ? Optional.empty()
         : Optional.of(
            this.incompatibilities
               .stream()
               .map(OpenIDConnectIncompatibility::getMessage)
               .collect(Collectors.joining("\n* ", "Found incompatibilities:\n* ", ""))
         );
   }

   public Optional<String> getWarningMessage() {
      return this.warnings.isEmpty()
         ? Optional.empty()
         : Optional.of(this.warnings.stream().map(OpenIDConnectCompatibilityWarning::getMessage).collect(Collectors.joining("\n* ", "Warnings:\n* ", "")));
   }

   public OpenIDConnectCompatibilityResult merged(OpenIDConnectCompatibilityResult other) {
      List<OpenIDConnectIncompatibility> mergedIncompatibilities = Lists.newArrayList(this.incompatibilities);
      mergedIncompatibilities.addAll(other.incompatibilities);
      List<OpenIDConnectCompatibilityWarning> mergedWarnings = Lists.newArrayList(this.warnings);
      mergedWarnings.addAll(other.warnings);
      return new OpenIDConnectCompatibilityResult(mergedIncompatibilities, mergedWarnings);
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public List<OpenIDConnectIncompatibility> getIncompatibilities() {
      return this.incompatibilities;
   }

   @SuppressFBWarnings(justification = "generated code")
   public List<OpenIDConnectCompatibilityWarning> getWarnings() {
      return this.warnings;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof OpenIDConnectCompatibilityResult other)) {
         return false;
      } else {
         Object this$incompatibilities = this.incompatibilities;
         Object other$incompatibilities = other.incompatibilities;
         if (this$incompatibilities == null ? other$incompatibilities == null : this$incompatibilities.equals(other$incompatibilities)) {
            Object this$warnings = this.warnings;
            Object other$warnings = other.warnings;
            return this$warnings == null ? other$warnings == null : this$warnings.equals(other$warnings);
         } else {
            return false;
         }
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      Object $incompatibilities = this.incompatibilities;
      result = result * 59 + ($incompatibilities == null ? 43 : $incompatibilities.hashCode());
      Object $warnings = this.warnings;
      return result * 59 + ($warnings == null ? 43 : $warnings.hashCode());
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "OpenIDConnectCompatibilityResult(incompatibilities=" + this.getIncompatibilities() + ", warnings=" + this.getWarnings() + ")";
   }

   @SuppressFBWarnings(justification = "generated code")
   public OpenIDConnectCompatibilityResult(List<OpenIDConnectIncompatibility> incompatibilities, List<OpenIDConnectCompatibilityWarning> warnings) {
      this.incompatibilities = incompatibilities;
      this.warnings = warnings;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OpenIDConnectCompatibilityResultBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<OpenIDConnectIncompatibility> incompatibilities;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<OpenIDConnectCompatibilityWarning> warnings;

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder incompatibility(OpenIDConnectIncompatibility incompatibility) {
         if (this.incompatibilities == null) {
            this.incompatibilities = new ArrayList<>();
         }

         this.incompatibilities.add(incompatibility);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder incompatibilities(
         Collection<? extends OpenIDConnectIncompatibility> incompatibilities
      ) {
         if (incompatibilities == null) {
            throw new NullPointerException("incompatibilities cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder clearIncompatibilities() {
         if (this.incompatibilities != null) {
            this.incompatibilities.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder warning(OpenIDConnectCompatibilityWarning warning) {
         if (this.warnings == null) {
            this.warnings = new ArrayList<>();
         }

         this.warnings.add(warning);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder warnings(Collection<? extends OpenIDConnectCompatibilityWarning> warnings) {
         if (warnings == null) {
            throw new NullPointerException("warnings cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder clearWarnings() {
         if (this.warnings != null) {
            this.warnings.clear();
         }

         return this;
      }

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

         return new OpenIDConnectCompatibilityResult(incompatibilities, switch (this.warnings == null ? 0 : this.warnings.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.warnings.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.warnings));
         });
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OpenIDConnectCompatibilityResult.OpenIDConnectCompatibilityResultBuilder(incompatibilities="
            + this.incompatibilities
            + ", warnings="
            + this.warnings
            + ")";
      }
   }
}
