package com.oguerreiro.resilient.service.criteria;

import java.util.Objects;
import java.util.Optional;

import org.springdoc.core.annotations.ParameterObject;

import com.oguerreiro.resilient.domain.enumeration.InputMode;

import tech.jhipster.service.filter.BooleanFilter;
import tech.jhipster.service.filter.Filter;
import tech.jhipster.service.filter.IntegerFilter;
import tech.jhipster.service.filter.LongFilter;
import tech.jhipster.service.filter.StringFilter;

/**
 * Criteria class for the {@link com.oguerreiro.resilient.domain.Variable} entity. This class is used
 * in {@link com.oguerreiro.resilient.web.rest.VariableResource} to receive all the possible filtering options from
 * the Http GET request parameters.
 * For example the following could be a valid request:
 * {@code /variables?id.greaterThan=5&attr1.contains=something&attr2.specified=false}
 * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use
 * fix type specific filters.
 */
@ParameterObject
public class VariableCriteria extends AbstractCriteria {

  /**
   * Class for filtering InputMode
   */
  public static class InputModeFilter extends Filter<InputMode> {
    private static final long serialVersionUID = 1L;

    public InputModeFilter() {
    }

    public InputModeFilter(InputModeFilter filter) {
      super(filter);
    }

    @Override
    public InputModeFilter copy() {
      return new InputModeFilter(this);
    }
  }

  private static final long serialVersionUID = 1L;

  private LongFilter id;

  private StringFilter code;

  private IntegerFilter variableIndex;

  private StringFilter name;

  private StringFilter description;

  private BooleanFilter input;

  private InputModeFilter inputMode;

  private BooleanFilter output;

  private StringFilter outputFormula;

  private IntegerFilter version;

  private LongFilter variableClassId;

  private LongFilter variableUnitsId;

  private LongFilter baseUnitId;

  private LongFilter variableScopeId;

  private LongFilter variableCategoryId;

  public VariableCriteria() {
    super();
  }

  public VariableCriteria(VariableCriteria other) {
    super(other);

    this.id = other.optionalId().map(LongFilter::copy).orElse(null);
    this.code = other.optionalCode().map(StringFilter::copy).orElse(null);
    this.variableIndex = other.optionalVariableIndex().map(IntegerFilter::copy).orElse(null);
    this.name = other.optionalName().map(StringFilter::copy).orElse(null);
    this.description = other.optionalDescription().map(StringFilter::copy).orElse(null);
    this.input = other.optionalInput().map(BooleanFilter::copy).orElse(null);
    this.inputMode = other.optionalInputMode().map(InputModeFilter::copy).orElse(null);
    this.output = other.optionalOutput().map(BooleanFilter::copy).orElse(null);
    this.outputFormula = other.optionalOutputFormula().map(StringFilter::copy).orElse(null);
    this.version = other.optionalVersion().map(IntegerFilter::copy).orElse(null);
    this.variableUnitsId = other.optionalVariableUnitsId().map(LongFilter::copy).orElse(null);
    this.baseUnitId = other.optionalBaseUnitId().map(LongFilter::copy).orElse(null);
    this.variableScopeId = other.optionalVariableScopeId().map(LongFilter::copy).orElse(null);
    this.variableCategoryId = other.optionalVariableCategoryId().map(LongFilter::copy).orElse(null);
  }

  @Override
  public VariableCriteria copy() {
    return new VariableCriteria(this);
  }

  public LongFilter getId() {
    return id;
  }

  public Optional<LongFilter> optionalId() {
    return Optional.ofNullable(id);
  }

  public LongFilter id() {
    if (id == null) {
      setId(new LongFilter());
    }
    return id;
  }

  public void setId(LongFilter id) {
    this.id = id;
  }

  public StringFilter getCode() {
    return code;
  }

  public Optional<StringFilter> optionalCode() {
    return Optional.ofNullable(code);
  }

  public StringFilter code() {
    if (code == null) {
      setCode(new StringFilter());
    }
    return code;
  }

  public void setCode(StringFilter code) {
    this.code = code;
  }

  public IntegerFilter getVariableIndex() {
    return variableIndex;
  }

  public Optional<IntegerFilter> optionalVariableIndex() {
    return Optional.ofNullable(variableIndex);
  }

  public IntegerFilter variableIndex() {
    if (variableIndex == null) {
      setVariableIndex(new IntegerFilter());
    }
    return variableIndex;
  }

  public void setVariableIndex(IntegerFilter variableIndex) {
    this.variableIndex = variableIndex;
  }

  public StringFilter getName() {
    return name;
  }

  public Optional<StringFilter> optionalName() {
    return Optional.ofNullable(name);
  }

  public StringFilter name() {
    if (name == null) {
      setName(new StringFilter());
    }
    return name;
  }

  public void setName(StringFilter name) {
    this.name = name;
  }

  public StringFilter getDescription() {
    return description;
  }

  public Optional<StringFilter> optionalDescription() {
    return Optional.ofNullable(description);
  }

  public StringFilter description() {
    if (description == null) {
      setDescription(new StringFilter());
    }
    return description;
  }

  public void setDescription(StringFilter description) {
    this.description = description;
  }

  public BooleanFilter getInput() {
    return input;
  }

  public Optional<BooleanFilter> optionalInput() {
    return Optional.ofNullable(input);
  }

  public BooleanFilter input() {
    if (input == null) {
      setInput(new BooleanFilter());
    }
    return input;
  }

  public void setInput(BooleanFilter input) {
    this.input = input;
  }

  public InputModeFilter getInputMode() {
    return inputMode;
  }

  public Optional<InputModeFilter> optionalInputMode() {
    return Optional.ofNullable(inputMode);
  }

  public InputModeFilter inputMode() {
    if (inputMode == null) {
      setInputMode(new InputModeFilter());
    }
    return inputMode;
  }

  public void setInputMode(InputModeFilter inputMode) {
    this.inputMode = inputMode;
  }

  public BooleanFilter getOutput() {
    return output;
  }

  public Optional<BooleanFilter> optionalOutput() {
    return Optional.ofNullable(output);
  }

  public BooleanFilter output() {
    if (output == null) {
      setOutput(new BooleanFilter());
    }
    return output;
  }

  public void setOutput(BooleanFilter output) {
    this.output = output;
  }

  public StringFilter getOutputFormula() {
    return outputFormula;
  }

  public Optional<StringFilter> optionalOutputFormula() {
    return Optional.ofNullable(outputFormula);
  }

  public StringFilter outputFormula() {
    if (outputFormula == null) {
      setOutputFormula(new StringFilter());
    }
    return outputFormula;
  }

  public void setOutputFormula(StringFilter outputFormula) {
    this.outputFormula = outputFormula;
  }

  public IntegerFilter getVersion() {
    return version;
  }

  public Optional<IntegerFilter> optionalVersion() {
    return Optional.ofNullable(version);
  }

  public IntegerFilter version() {
    if (version == null) {
      setVersion(new IntegerFilter());
    }
    return version;
  }

  public void setVersion(IntegerFilter version) {
    this.version = version;
  }

  public void setVariableClassId(LongFilter variableClassId) {
    this.variableClassId = variableClassId;
  }

  public LongFilter getVariableUnitsId() {
    return variableUnitsId;
  }

  public Optional<LongFilter> optionalVariableUnitsId() {
    return Optional.ofNullable(variableUnitsId);
  }

  public LongFilter variableUnitsId() {
    if (variableUnitsId == null) {
      setVariableUnitsId(new LongFilter());
    }
    return variableUnitsId;
  }

  public void setVariableUnitsId(LongFilter variableUnitsId) {
    this.variableUnitsId = variableUnitsId;
  }

  public LongFilter getBaseUnitId() {
    return baseUnitId;
  }

  public Optional<LongFilter> optionalBaseUnitId() {
    return Optional.ofNullable(baseUnitId);
  }

  public LongFilter baseUnitId() {
    if (baseUnitId == null) {
      setBaseUnitId(new LongFilter());
    }
    return baseUnitId;
  }

  public void setBaseUnitId(LongFilter baseUnitId) {
    this.baseUnitId = baseUnitId;
  }

  public LongFilter getVariableScopeId() {
    return variableScopeId;
  }

  public Optional<LongFilter> optionalVariableScopeId() {
    return Optional.ofNullable(variableScopeId);
  }

  public LongFilter variableScopeId() {
    if (variableScopeId == null) {
      setVariableScopeId(new LongFilter());
    }
    return variableScopeId;
  }

  public void setVariableScopeId(LongFilter variableScopeId) {
    this.variableScopeId = variableScopeId;
  }

  public LongFilter getVariableCategoryId() {
    return variableCategoryId;
  }

  public Optional<LongFilter> optionalVariableCategoryId() {
    return Optional.ofNullable(variableCategoryId);
  }

  public LongFilter variableCategoryId() {
    if (variableCategoryId == null) {
      setVariableCategoryId(new LongFilter());
    }
    return variableCategoryId;
  }

  public void setVariableCategoryId(LongFilter variableCategoryId) {
    this.variableCategoryId = variableCategoryId;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    final VariableCriteria that = (VariableCriteria) o;
    return (Objects.equals(id, that.id) && Objects.equals(code, that.code)
        && Objects.equals(variableIndex, that.variableIndex) && Objects.equals(name, that.name)
        && Objects.equals(description, that.description) && Objects.equals(input, that.input)
        && Objects.equals(inputMode, that.inputMode) && Objects.equals(output, that.output)
        && Objects.equals(outputFormula, that.outputFormula) && Objects.equals(version, that.version)
        && Objects.equals(variableClassId, that.variableClassId)
        && Objects.equals(variableUnitsId, that.variableUnitsId) && Objects.equals(baseUnitId, that.baseUnitId)
        && Objects.equals(variableScopeId, that.variableScopeId)
        && Objects.equals(variableCategoryId, that.variableCategoryId) && super.equals(o));
  }

  @Override
  public int hashCode() {
    return Objects.hash(id, code, variableIndex, name, description, input, inputMode, output, outputFormula, version,
        variableClassId, variableUnitsId, baseUnitId, variableScopeId, variableCategoryId, super.hashCode());
  }

  // prettier-ignore
  @Override
  public String toString() {
    return "VariableCriteria{" + optionalId().map(f -> "id=" + f + ", ").orElse("")
        + optionalCode().map(f -> "code=" + f + ", ").orElse("")
        + optionalVariableIndex().map(f -> "variableIndex=" + f + ", ").orElse("")
        + optionalName().map(f -> "name=" + f + ", ").orElse("")
        + optionalDescription().map(f -> "description=" + f + ", ").orElse("")
        + optionalInput().map(f -> "input=" + f + ", ").orElse("")
        + optionalInputMode().map(f -> "inputMode=" + f + ", ").orElse("")
        + optionalOutput().map(f -> "output=" + f + ", ").orElse("")
        + optionalOutputFormula().map(f -> "outputFormula=" + f + ", ").orElse("")
        + optionalVersion().map(f -> "version=" + f + ", ").orElse("")
        + optionalVariableUnitsId().map(f -> "variableUnitsId=" + f + ", ").orElse("")
        + optionalBaseUnitId().map(f -> "baseUnitId=" + f + ", ").orElse("")
        + optionalVariableScopeId().map(f -> "variableScopeId=" + f + ", ").orElse("")
        + optionalVariableCategoryId().map(f -> "variableCategoryId=" + f + ", ").orElse("") + super.toString() + "}";
  }
}
