package com.oguerreiro.resilient.domain;

import java.math.BigDecimal;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.oguerreiro.resilient.security.custom.ResilientSecurityResourceConfig;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;

/**
 * Output data Values
 * The values calculated using the Variable.outputFormula, for all variables with Variable.output==TRUE.
 */
@Entity
@Table(name = "output_data")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@ResilientSecurityResourceConfig()
public class OutputData extends AbstractResilientLongIdEntity<OutputData> {

  private static final long serialVersionUID = 1L;

  /**
   * The evaluated value, calculated by Variable.outputFormula. This will probably represent an emission value.
   */
  @NotNull
  @Column(name = "value", precision = 21, scale = 2, nullable = false)
  private BigDecimal value;

  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties(value = { "variableClasses", "inputData", "outputData", "variableUnits", "baseUnit",
      "variableScope", "variableCategory" }, allowSetters = true)
  private Variable variable;

  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties(value = { "periodVersions" }, allowSetters = true)
  private Period period;

  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties(value = { "period" }, allowSetters = true)
  private PeriodVersion periodVersion;

  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties(value = { "fromUnits", "toUnits", "baseUnits", "sourceUnits", "inputData", "outputData",
      "variableUnits", "unitType" }, allowSetters = true)
  private Unit baseUnit;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties(value = { "user", "children", "parent", "organizationType" }, allowSetters = true)
  private Organization owner;

  public BigDecimal getValue() {
    return this.value;
  }

  public OutputData value(BigDecimal value) {
    this.setValue(value);
    return this;
  }

  public void setValue(BigDecimal value) {
    this.value = value;
  }

  public Variable getVariable() {
    return this.variable;
  }

  public void setVariable(Variable variable) {
    this.variable = variable;
  }

  public OutputData variable(Variable variable) {
    this.setVariable(variable);
    return this;
  }

  public Period getPeriod() {
    return this.period;
  }

  public void setPeriod(Period period) {
    this.period = period;
  }

  public OutputData period(Period period) {
    this.setPeriod(period);
    return this;
  }

  public PeriodVersion getPeriodVersion() {
    return this.periodVersion;
  }

  public void setPeriodVersion(PeriodVersion periodVersion) {
    this.periodVersion = periodVersion;
  }

  public OutputData periodVersion(PeriodVersion periodVersion) {
    this.setPeriodVersion(periodVersion);
    return this;
  }

  public Unit getBaseUnit() {
    return this.baseUnit;
  }

  public void setBaseUnit(Unit unit) {
    this.baseUnit = unit;
  }

  public OutputData baseUnit(Unit unit) {
    this.setBaseUnit(unit);
    return this;
  }

  public Organization getOwner() {
    return this.owner;
  }

  public void setOwner(Organization organization) {
    this.owner = organization;
  }

  public OutputData owner(Organization organization) {
    this.setOwner(organization);
    return this;
  }

//@formatter:off
  @Override
  public String toString() {
    return "OutputData{" + 
              "id=" + getId() + 
              ", value=" + getValue() + 
              ", version=" + getVersion() + 
            "}";
  }
//@formatter:on
}
