package com.oguerreiro.resilient.domain;

import java.time.Instant;

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

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

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

/**
 * Period versions Always have at least one version.
 */
@Entity
@Table(name = "period_version")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@ResilientSecurityResourceConfig()
public class PeriodVersion extends AbstractResilientLongIdEntity<PeriodVersion> {

  private static final long serialVersionUID = 1L;

  /**
   * Name of the version
   */
  @NotNull
  @Column(name = "name", nullable = false)
  private String name;

  /**
   * Description for the version
   */
  @Column(name = "description")
  private String description;

  /**
   * Period version (sequencial)
   */
  @NotNull
  @Column(name = "period_version", nullable = false)
  private Integer periodVersion;

  /**
   * State of the Period
   */
  @NotNull
  @Enumerated(EnumType.STRING)
  @Column(name = "state", nullable = false)
  private PeriodVersionStatus state;

  /**
   * The creation date (insert). When the data was inserted into the system.
   */
  @NotNull
  @Column(name = "creation_date", nullable = false)
  private Instant creationDate;

  /**
   * The actual username logged into the system, that inserted the data. NOT a
   * reference to the user, but the login username.
   */
  @NotNull
  @Column(name = "creation_username", nullable = false)
  private String creationUsername;

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

  public String getName() {
    return this.name;
  }

  public PeriodVersion name(String name) {
    this.setName(name);
    return this;
  }

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

  public String getDescription() {
    return this.description;
  }

  public PeriodVersion description(String description) {
    this.setDescription(description);
    return this;
  }

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

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

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

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

  public PeriodVersionStatus getState() {
    return this.state;
  }

  public PeriodVersion state(PeriodVersionStatus state) {
    this.setState(state);
    return this;
  }

  public void setState(PeriodVersionStatus state) {
    this.state = state;
  }

  public Instant getCreationDate() {
    return this.creationDate;
  }

  public PeriodVersion creationDate(Instant creationDate) {
    this.setCreationDate(creationDate);
    return this;
  }

  public void setCreationDate(Instant creationDate) {
    this.creationDate = creationDate;
  }

  public String getCreationUsername() {
    return this.creationUsername;
  }

  public PeriodVersion creationUsername(String creationUsername) {
    this.setCreationUsername(creationUsername);
    return this;
  }

  public void setCreationUsername(String creationUsername) {
    this.creationUsername = creationUsername;
  }

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

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

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

//@formatter:off
  @Override
  public String toString() {
    return "PeriodVersion{" + 
              "id=" + getId() + 
              ", name='" + getName() + "'" + 
              ", description='" + getDescription() + "'" + 
              ", periodVersion=" + getPeriodVersion() + 
              ", state='" + getState() + "'" + 
              ", creationDate='" + getCreationDate() + "'" + 
              ", creationUsername='" + getCreationUsername() + "'" + 
              ", version=" + getVersion() + 
           "}";
  }
//@formatter:on
}
