package com.airlock.iam.common.domain.model.contextdata;

import com.airlock.iam.base.api.domain.model.validation.ValidationResult;
import com.airlock.iam.common.api.domain.model.contextdata.ContextDataItem;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Objects;
import java.util.Optional;

public final class ContextDataItemImpl<T> implements ContextDataItem<T> {
   private final String key;
   private final T value;
   private final boolean visible;
   private final boolean editable;
   private final Optional<ContextDataItemValidator<T>> itemValidator;

   public ContextDataItemImpl(String key, T value) {
      this(key, value, true, true, Optional.empty());
   }

   public ContextDataItemImpl(String key, T value, boolean visible, boolean editable, Optional<ContextDataItemValidator<T>> itemValidator) {
      this.key = key;
      this.visible = visible;
      this.editable = editable;
      this.value = value;
      this.itemValidator = itemValidator;
   }

   @Override
   public ValidationResult validate(Optional<ContextDataItem<T>> previousItem) {
      return this.itemValidator.isPresent()
         ? this.itemValidator.get().validate(this.value, previousItem.map(ContextDataItem::getValue))
         : ValidationResult.valid();
   }

   @Override
   public int hashCode() {
      return this.key.hashCode();
   }

   @Override
   public boolean equals(Object obj) {
      return !(obj instanceof ContextDataItem<T> other) ? false : Objects.equals(this.key, other.getKey()) && Objects.equals(this.value, other.getValue());
   }

   @SuppressFBWarnings(justification = "generated code")
   public static <T> ContextDataItemImpl.ContextDataItemImplBuilder<T> builder() {
      return new ContextDataItemImpl.ContextDataItemImplBuilder<>();
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String getKey() {
      return this.key;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public T getValue() {
      return this.value;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean isVisible() {
      return this.visible;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean isEditable() {
      return this.editable;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Optional<ContextDataItemValidator<T>> getItemValidator() {
      return this.itemValidator;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "ContextDataItemImpl(key="
         + this.getKey()
         + ", value="
         + this.getValue()
         + ", visible="
         + this.isVisible()
         + ", editable="
         + this.isEditable()
         + ", itemValidator="
         + this.getItemValidator()
         + ")";
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class ContextDataItemImplBuilder<T> {
      @SuppressFBWarnings(justification = "generated code")
      private String key;
      @SuppressFBWarnings(justification = "generated code")
      private T value;
      @SuppressFBWarnings(justification = "generated code")
      private boolean visible;
      @SuppressFBWarnings(justification = "generated code")
      private boolean editable;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<ContextDataItemValidator<T>> itemValidator;

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

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataItemImpl.ContextDataItemImplBuilder<T> key(String key) {
         this.key = key;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataItemImpl.ContextDataItemImplBuilder<T> value(T value) {
         this.value = value;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataItemImpl.ContextDataItemImplBuilder<T> visible(boolean visible) {
         this.visible = visible;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataItemImpl.ContextDataItemImplBuilder<T> editable(boolean editable) {
         this.editable = editable;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataItemImpl.ContextDataItemImplBuilder<T> itemValidator(Optional<ContextDataItemValidator<T>> itemValidator) {
         this.itemValidator = itemValidator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataItemImpl<T> build() {
         return new ContextDataItemImpl<>(this.key, this.value, this.visible, this.editable, this.itemValidator);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "ContextDataItemImpl.ContextDataItemImplBuilder(key="
            + this.key
            + ", value="
            + this.value
            + ", visible="
            + this.visible
            + ", editable="
            + this.editable
            + ", itemValidator="
            + this.itemValidator
            + ")";
      }
   }
}
