package com.airlock.iam.common.application.service.validation;

import com.airlock.iam.base.api.domain.model.validation.GenericError;
import com.airlock.iam.base.api.domain.model.validation.ValidationResult;
import com.airlock.iam.base.api.domain.model.validation.Validator;
import com.airlock.iam.base.api.domain.model.validation.ValidatorError;
import com.airlock.iam.core.misc.util.DateRange;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public final class DateRangeValidator implements Validator<DateRange> {
   private final boolean mandatoryFrom;
   private final boolean mandatoryTo;
   private final String fromFieldName;
   private final String toFieldName;

   public ValidationResult validate(DateRange range) {
      List<ValidatorError> errors = new ArrayList<>();
      if (this.mandatoryFrom && range.getFromInstant() == null) {
         errors.add(ValidatorError.validatorError(this.fromFieldName, GenericError.REQUIRED));
      }

      if (this.mandatoryTo && range.getToInstant() == null) {
         errors.add(ValidatorError.validatorError(this.toFieldName, GenericError.REQUIRED));
      }

      if (range.bothDatesSet() && Objects.requireNonNull(range.getToInstant()).isBefore(Objects.requireNonNull(range.getFromInstant()))) {
         errors.add(ValidatorError.validatorErrorBuilder(this.toFieldName, GenericError.AFTER).parameter("after", range.getFromDate()).build());
      }

      return errors.isEmpty() ? ValidationResult.valid() : ValidationResult.invalid(errors);
   }

   @SuppressFBWarnings(justification = "generated code")
   DateRangeValidator(boolean mandatoryFrom, boolean mandatoryTo, String fromFieldName, String toFieldName) {
      this.mandatoryFrom = mandatoryFrom;
      this.mandatoryTo = mandatoryTo;
      this.fromFieldName = fromFieldName;
      this.toFieldName = toFieldName;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class DateRangeValidatorBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private boolean mandatoryFrom;
      @SuppressFBWarnings(justification = "generated code")
      private boolean mandatoryTo;
      @SuppressFBWarnings(justification = "generated code")
      private String fromFieldName;
      @SuppressFBWarnings(justification = "generated code")
      private String toFieldName;

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

      @SuppressFBWarnings(justification = "generated code")
      public DateRangeValidator.DateRangeValidatorBuilder mandatoryFrom(boolean mandatoryFrom) {
         this.mandatoryFrom = mandatoryFrom;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateRangeValidator.DateRangeValidatorBuilder mandatoryTo(boolean mandatoryTo) {
         this.mandatoryTo = mandatoryTo;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateRangeValidator.DateRangeValidatorBuilder fromFieldName(String fromFieldName) {
         this.fromFieldName = fromFieldName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateRangeValidator.DateRangeValidatorBuilder toFieldName(String toFieldName) {
         this.toFieldName = toFieldName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateRangeValidator build() {
         return new DateRangeValidator(this.mandatoryFrom, this.mandatoryTo, this.fromFieldName, this.toFieldName);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "DateRangeValidator.DateRangeValidatorBuilder(mandatoryFrom="
            + this.mandatoryFrom
            + ", mandatoryTo="
            + this.mandatoryTo
            + ", fromFieldName="
            + this.fromFieldName
            + ", toFieldName="
            + this.toFieldName
            + ")";
      }
   }
}
