package org.etsi.osl.tmf.pm628.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Size;
import org.etsi.osl.tmf.common.model.BaseRootEntity;
import org.springframework.format.annotation.DateTimeFormat;

import javax.annotation.Generated;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * ManagementJob
 */

@JsonIgnoreProperties(
  value = "@type", // ignore manually set @type, it will be automatically generated by Jackson during serialization
  allowSetters = true // allows the @type to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = ManagementJob.class, name = "ManagementJob"),
  @JsonSubTypes.Type(value = MeasurementCollectionJob.class, name = "MeasurementCollectionJob"),
  @JsonSubTypes.Type(value = MeasurementJob.class, name = "MeasurementJob")
})

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-05-15T07:30:16.936523289Z[Etc/UTC]", comments = "Generator version: 7.6.0-SNAPSHOT")
@Entity(name = "PM628_ManJob")
public class ManagementJob extends BaseRootEntity {

  @JsonProperty("adminState")
  private AdministrativeState adminState;

  @JsonProperty("creationTime")
  @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
  private OffsetDateTime creationTime;

  @JsonProperty("executionState")
  private ExecutionStateType executionState;

  @JsonProperty("fileTransferData")
  @Valid
  @ElementCollection(targetClass = FileTransferData.class)
  @CollectionTable(
          name = "pm628_man_job_ftd",
          joinColumns = @JoinColumn(name = "man_job_id")
  )
  private List<FileTransferData> fileTransferData = new ArrayList<>();

  @JsonProperty("dataAccessEndpoint")
  @Valid
  @OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
  @JoinTable(
          name = "pm628_man_job_dae",
          joinColumns = @JoinColumn(name = "man_job_uuid"),
          inverseJoinColumns = @JoinColumn(name = "dae_uuid")
  )
  private List<DataAccessEndpoint> dataAccessEndpoint = new ArrayList<>();

  @JsonProperty("jobId")
  private String jobId;

  @JsonProperty("jobPriority")
  private Integer jobPriority = 5;

  @JsonProperty("lastModifiedTime")
  @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
  private OffsetDateTime lastModifiedTime;

  @JsonProperty("scheduleDefinition")
  @Valid
  @OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
  @JoinTable(
          name = "pm628_man_job_shched_def",
          joinColumns = @JoinColumn(name = "man_job_uuid"),
          inverseJoinColumns = @JoinColumn(name = "sched_def_uuid")
  )
  private List<ScheduleDefinition> scheduleDefinition = new ArrayList<>();

  public ManagementJob() {
    super();
  }

  /**
   * Constructor with only required parameters
   */
  public ManagementJob(String type) {
    this.type = type;
  }

  public ManagementJob adminState(AdministrativeState adminState) {
    this.adminState = adminState;
    return this;
  }

  /**
   * Get adminState
   * @return adminState
  */
  @Valid 
  @Schema(name = "adminState", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("adminState")
  public AdministrativeState getAdminState() {
    return adminState;
  }

  public void setAdminState(AdministrativeState adminState) {
    this.adminState = adminState;
  }

  public ManagementJob creationTime(OffsetDateTime creationTime) {
    this.creationTime = creationTime;
    return this;
  }

  /**
   * The measurement job creation time.
   * @return creationTime
  */
  @Valid 
  @Schema(name = "creationTime", description = "The measurement job creation time.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("creationTime")
  public OffsetDateTime getCreationTime() {
    return creationTime;
  }

  public void setCreationTime(OffsetDateTime creationTime) {
    this.creationTime = creationTime;
  }

  public ManagementJob executionState(ExecutionStateType executionState) {
    this.executionState = executionState;
    return this;
  }

  /**
   * Get executionState
   * @return executionState
  */
  @Valid 
  @Schema(name = "executionState", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("executionState")
  public ExecutionStateType getExecutionState() {
    return executionState;
  }

  public void setExecutionState(ExecutionStateType executionState) {
    this.executionState = executionState;
  }

  public ManagementJob fileTransferData(List<FileTransferData> fileTransferData) {
    this.fileTransferData = fileTransferData;
    return this;
  }

  public ManagementJob addFileTransferDataItem(FileTransferData fileTransferDataItem) {
    if (this.fileTransferData == null) {
      this.fileTransferData = new ArrayList<>();
    }
    this.fileTransferData.add(fileTransferDataItem);
    return this;
  }

  /**
   * Get fileTransferData
   * @return fileTransferData
  */
  @Valid @Size(min = 0) 
  @Schema(name = "fileTransferData", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("fileTransferData")
  public List<FileTransferData> getFileTransferData() {
    return fileTransferData;
  }

  public void setFileTransferData(List<FileTransferData> fileTransferData) {
    this.fileTransferData = fileTransferData;
  }

  public ManagementJob dataAccessEndpoint(List<DataAccessEndpoint> dataAccessEndpoint) {
    this.dataAccessEndpoint = dataAccessEndpoint;
    return this;
  }

  public ManagementJob addDataAccessEndpointItem(DataAccessEndpoint dataAccessEndpointItem) {
    if (this.dataAccessEndpoint == null) {
      this.dataAccessEndpoint = new ArrayList<>();
    }
    this.dataAccessEndpoint.add(dataAccessEndpointItem);
    return this;
  }

  /**
   * Get dataAccessEndpoint
   * @return dataAccessEndpoint
  */
  @Valid @Size(min = 0) 
  @Schema(name = "dataAccessEndpoint", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("dataAccessEndpoint")
  public List<DataAccessEndpoint> getDataAccessEndpoint() {
    return dataAccessEndpoint;
  }

  public void setDataAccessEndpoint(List<DataAccessEndpoint> dataAccessEndpoint) {
    this.dataAccessEndpoint = dataAccessEndpoint;
  }

  public ManagementJob jobId(String jobId) {
    this.jobId = jobId;
    return this;
  }

  /**
   * The ID of the management job.
   * @return jobId
  */
  
  @Schema(name = "jobId", description = "The ID of the management job.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("jobId")
  public String getJobId() {
    return jobId;
  }

  public void setJobId(String jobId) {
    this.jobId = jobId;
  }

  public ManagementJob jobPriority(Integer jobPriority) {
    this.jobPriority = jobPriority;
    return this;
  }

  /**
   * The priority of the management job. The way the management application will use the JobPriority to schedule job execution is application specific and outside the scope. Integer, limited to a range of 1 to 10.
   * minimum: 1
   * maximum: 10
   * @return jobPriority
  */
  @Min(1) @Max(10) 
  @Schema(name = "jobPriority", description = "The priority of the management job. The way the management application will use the JobPriority to schedule job execution is application specific and outside the scope. Integer, limited to a range of 1 to 10.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("jobPriority")
  public Integer getJobPriority() {
    return jobPriority;
  }

  public void setJobPriority(Integer jobPriority) {
    this.jobPriority = jobPriority;
  }

  public ManagementJob lastModifiedTime(OffsetDateTime lastModifiedTime) {
    this.lastModifiedTime = lastModifiedTime;
    return this;
  }

  /**
   * The last time that a measurement job was modified.
   * @return lastModifiedTime
  */
  @Valid 
  @Schema(name = "lastModifiedTime", description = "The last time that a measurement job was modified.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("lastModifiedTime")
  public OffsetDateTime getLastModifiedTime() {
    return lastModifiedTime;
  }

  public void setLastModifiedTime(OffsetDateTime lastModifiedTime) {
    this.lastModifiedTime = lastModifiedTime;
  }

  public ManagementJob scheduleDefinition(List<ScheduleDefinition> scheduleDefinition) {
    this.scheduleDefinition = scheduleDefinition;
    return this;
  }

  public ManagementJob addScheduleDefinitionItem(ScheduleDefinition scheduleDefinitionItem) {
    if (this.scheduleDefinition == null) {
      this.scheduleDefinition = new ArrayList<>();
    }
    this.scheduleDefinition.add(scheduleDefinitionItem);
    return this;
  }

  /**
   * Get scheduleDefinition
   * @return scheduleDefinition
  */
  @Valid @Size(max = 1) 
  @Schema(name = "scheduleDefinition", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("scheduleDefinition")
  public List<ScheduleDefinition> getScheduleDefinition() {
    return scheduleDefinition;
  }

  public void setScheduleDefinition(List<ScheduleDefinition> scheduleDefinition) {
    this.scheduleDefinition = scheduleDefinition;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    ManagementJob managementJob = (ManagementJob) o;
    return Objects.equals(this.type, managementJob.type) &&
        Objects.equals(this.baseType, managementJob.baseType) &&
        Objects.equals(this.schemaLocation, managementJob.schemaLocation) &&
        Objects.equals(this.href, managementJob.href) &&
        Objects.equals(this.uuid, managementJob.uuid) &&
        Objects.equals(this.adminState, managementJob.adminState) &&
        Objects.equals(this.creationTime, managementJob.creationTime) &&
        Objects.equals(this.executionState, managementJob.executionState) &&
        Objects.equals(this.fileTransferData, managementJob.fileTransferData) &&
        Objects.equals(this.dataAccessEndpoint, managementJob.dataAccessEndpoint) &&
        Objects.equals(this.jobId, managementJob.jobId) &&
        Objects.equals(this.jobPriority, managementJob.jobPriority) &&
        Objects.equals(this.lastModifiedTime, managementJob.lastModifiedTime) &&
        Objects.equals(this.scheduleDefinition, managementJob.scheduleDefinition);
  }

  @Override
  public int hashCode() {
    return Objects.hash(type, baseType, schemaLocation, href, uuid, adminState, creationTime, executionState, fileTransferData, dataAccessEndpoint, jobId, jobPriority, lastModifiedTime, scheduleDefinition);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class ManagementJob {\n");
    sb.append("    atType: ").append(toIndentedString(type)).append("\n");
    sb.append("    atBaseType: ").append(toIndentedString(baseType)).append("\n");
    sb.append("    atSchemaLocation: ").append(toIndentedString(schemaLocation)).append("\n");
    sb.append("    href: ").append(toIndentedString(href)).append("\n");
    sb.append("    id: ").append(toIndentedString(uuid)).append("\n");
    sb.append("    adminState: ").append(toIndentedString(adminState)).append("\n");
    sb.append("    creationTime: ").append(toIndentedString(creationTime)).append("\n");
    sb.append("    executionState: ").append(toIndentedString(executionState)).append("\n");
    sb.append("    fileTransferData: ").append(toIndentedString(fileTransferData)).append("\n");
    sb.append("    dataAccessEndpoint: ").append(toIndentedString(dataAccessEndpoint)).append("\n");
    sb.append("    jobId: ").append(toIndentedString(jobId)).append("\n");
    sb.append("    jobPriority: ").append(toIndentedString(jobPriority)).append("\n");
    sb.append("    lastModifiedTime: ").append(toIndentedString(lastModifiedTime)).append("\n");
    sb.append("    scheduleDefinition: ").append(toIndentedString(scheduleDefinition)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}

