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.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import org.hibernate.annotations.*;

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

/**
 * MeasurementJob
 */

@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 = MeasurementCollectionJob.class, name = "MeasurementCollectionJob")
})

@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_MeasJob")
public class MeasurementJob extends ManagementJob {

  @JsonProperty("consumingApplicationId")
  private String consumingApplicationId;

  @JsonProperty("producingApplicationId")
  private String producingApplicationId;

  @JsonProperty("granularity")
  private Granularity granularity;

  @JsonProperty("performanceIndicatorGroupSpecification")
  @Valid
  @ManyToMany(cascade = {  CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
  @JoinTable(
          name = "pm628_meas_job_perf_ind_group_spec",
          joinColumns = @JoinColumn(name = "meas_job_uuid"),
          inverseJoinColumns = @JoinColumn(name = "perf_ind_group_spec_uuid")
  )
  private List<PerformanceIndicatorGroupSpecification> performanceIndicatorGroupSpecification = new ArrayList<>();

  @JsonProperty("performanceIndicatorSpecification")
  @Valid
  @ManyToAny
  @AnyDiscriminator(DiscriminatorType.STRING)
  @Column(name = "perf_ind_spec_type")
  @AnyKeyJavaClass(String.class)
  @AnyDiscriminatorValue(discriminator = "value", entity = PerformanceIndicatorSpecification.class)
  @AnyDiscriminatorValue(discriminator = "ref", entity = PerformanceIndicatorSpecificationRef.class)
  @Cascade({org.hibernate.annotations.CascadeType.MERGE, org.hibernate.annotations.CascadeType.PERSIST})
  @JoinTable(
          name = "pm628_meas_job_perf_ind_specs",
          joinColumns = @JoinColumn(name = "meas_job_uuid"),
          inverseJoinColumns = @JoinColumn(name = "perf_ind_spec_uuid")
  )
  private List<@Valid PerformanceIndicatorSpecificationRefOrValue> performanceIndicatorSpecification = new ArrayList<>();

  @JsonProperty("trackingRecord")
  @Valid
  @OneToMany(cascade = {  CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
  @JoinTable(
          name = "pm628_meas_job_track_rec",
          joinColumns = @JoinColumn(name = "meas_job_uuid"),
          inverseJoinColumns = @JoinColumn(name = "track_rec_uuid")
  )
  private List<TrackingRecord> trackingRecord = new ArrayList<>();

  @JsonProperty("monitoredInstancesCriteria")
  @Embedded
  private MonitoredInstancesCriteria monitoredInstancesCriteria;

  @JsonProperty("monitoredClassCriteria")
  @Embedded
  private MonitoredClassCriteria monitoredClassCriteria;

  public MeasurementJob() {
    super();
  }

  /**
   * Constructor with only required parameters
   */
  public MeasurementJob(String atType) {
    super(atType);
  }

  public MeasurementJob consumingApplicationId(String consumingApplicationId) {
    this.consumingApplicationId = consumingApplicationId;
    return this;
  }

  /**
   * The identifier of the application that consumes performance indicators.
   * @return consumingApplicationId
  */
  
  @Schema(name = "consumingApplicationId", description = "The identifier of the application that consumes performance indicators.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public String getConsumingApplicationId() {
    return consumingApplicationId;
  }

  public void setConsumingApplicationId(String consumingApplicationId) {
    this.consumingApplicationId = consumingApplicationId;
  }

  public MeasurementJob producingApplicationId(String producingApplicationId) {
    this.producingApplicationId = producingApplicationId;
    return this;
  }

  /**
   * The identifier of the application that produces performance indicators.
   * @return producingApplicationId
  */
  
  @Schema(name = "producingApplicationId", description = "The identifier of the application that produces performance indicators.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public String getProducingApplicationId() {
    return producingApplicationId;
  }

  public void setProducingApplicationId(String producingApplicationId) {
    this.producingApplicationId = producingApplicationId;
  }

  public MeasurementJob granularity(Granularity granularity) {
    this.granularity = granularity;
    return this;
  }

  /**
   * Get granularity
   * @return granularity
  */
  @Valid 
  @Schema(name = "granularity", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public Granularity getGranularity() {
    return granularity;
  }

  public void setGranularity(Granularity granularity) {
    this.granularity = granularity;
  }

  public MeasurementJob performanceIndicatorGroupSpecification(List<PerformanceIndicatorGroupSpecification> performanceIndicatorGroupSpecification) {
    this.performanceIndicatorGroupSpecification = performanceIndicatorGroupSpecification;
    return this;
  }

  public MeasurementJob addPerformanceIndicatorGroupSpecificationItem(PerformanceIndicatorGroupSpecification performanceIndicatorGroupSpecificationItem) {
    if (this.performanceIndicatorGroupSpecification == null) {
      this.performanceIndicatorGroupSpecification = new ArrayList<>();
    }
    this.performanceIndicatorGroupSpecification.add(performanceIndicatorGroupSpecificationItem);
    return this;
  }

  /**
   * Get performanceIndicatorGroupSpecification
   * @return performanceIndicatorGroupSpecification
  */
  @Valid @Size(min = 0) 
  @Schema(name = "performanceIndicatorGroupSpecification", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public List<PerformanceIndicatorGroupSpecification> getPerformanceIndicatorGroupSpecification() {
    return performanceIndicatorGroupSpecification;
  }

  public void setPerformanceIndicatorGroupSpecification(List<PerformanceIndicatorGroupSpecification> performanceIndicatorGroupSpecification) {
    this.performanceIndicatorGroupSpecification = performanceIndicatorGroupSpecification;
  }

  public MeasurementJob performanceIndicatorSpecification(List<@Valid PerformanceIndicatorSpecificationRefOrValue> performanceIndicatorSpecification) {
    this.performanceIndicatorSpecification = performanceIndicatorSpecification;
    return this;
  }

  public MeasurementJob addPerformanceIndicatorSpecificationItem(PerformanceIndicatorSpecificationRefOrValue performanceIndicatorSpecificationItem) {
    if (this.performanceIndicatorSpecification == null) {
      this.performanceIndicatorSpecification = new ArrayList<>();
    }
    this.performanceIndicatorSpecification.add(performanceIndicatorSpecificationItem);
    return this;
  }

  /**
   * Get performanceIndicatorSpecification
   * @return performanceIndicatorSpecification
  */
  @Valid @Size(min = 0) 
  @Schema(name = "performanceIndicatorSpecification", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public List<@Valid PerformanceIndicatorSpecificationRefOrValue> getPerformanceIndicatorSpecification() {
    return performanceIndicatorSpecification;
  }

  public void setPerformanceIndicatorSpecification(List<@Valid PerformanceIndicatorSpecificationRefOrValue> performanceIndicatorSpecification) {
    this.performanceIndicatorSpecification = performanceIndicatorSpecification;
  }

  public MeasurementJob trackingRecord(List<TrackingRecord> trackingRecord) {
    this.trackingRecord = trackingRecord;
    return this;
  }

  public MeasurementJob addTrackingRecordItem(TrackingRecord trackingRecordItem) {
    if (this.trackingRecord == null) {
      this.trackingRecord = new ArrayList<>();
    }
    this.trackingRecord.add(trackingRecordItem);
    return this;
  }

  /**
   * Get trackingRecord
   * @return trackingRecord
  */
  @Valid @Size(min = 0) 
  @Schema(name = "trackingRecord", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public List<TrackingRecord> getTrackingRecord() {
    return trackingRecord;
  }

  public void setTrackingRecord(List<TrackingRecord> trackingRecord) {
    this.trackingRecord = trackingRecord;
  }

  public MeasurementJob monitoredInstancesCriteria(MonitoredInstancesCriteria monitoredInstancesCriteria) {
    this.monitoredInstancesCriteria = monitoredInstancesCriteria;
    return this;
  }

  /**
   * Get monitoredInstancesCriteria
   * @return monitoredInstancesCriteria
  */
  @Valid 
  @Schema(name = "monitoredInstancesCriteria", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public MonitoredInstancesCriteria getMonitoredInstancesCriteria() {
    return monitoredInstancesCriteria;
  }

  public void setMonitoredInstancesCriteria(MonitoredInstancesCriteria monitoredInstancesCriteria) {
    this.monitoredInstancesCriteria = monitoredInstancesCriteria;
  }

  public MeasurementJob monitoredClassCriteria(MonitoredClassCriteria monitoredClassCriteria) {
    this.monitoredClassCriteria = monitoredClassCriteria;
    return this;
  }

  /**
   * Get monitoredClassCriteria
   * @return monitoredClassCriteria
  */
  @Valid 
  @Schema(name = "monitoredClassCriteria", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  public MonitoredClassCriteria getMonitoredClassCriteria() {
    return monitoredClassCriteria;
  }

  public void setMonitoredClassCriteria(MonitoredClassCriteria monitoredClassCriteria) {
    this.monitoredClassCriteria = monitoredClassCriteria;
  }

  public MeasurementJob adminState(AdministrativeState adminState) {
    super.adminState(adminState);
    return this;
  }

  public MeasurementJob creationTime(OffsetDateTime creationTime) {
    super.creationTime(creationTime);
    return this;
  }

  public MeasurementJob executionState(ExecutionStateType executionState) {
    super.executionState(executionState);
    return this;
  }

  public MeasurementJob fileTransferData(List<FileTransferData> fileTransferData) {
    super.fileTransferData(fileTransferData);
    return this;
  }

  public MeasurementJob addFileTransferDataItem(FileTransferData fileTransferDataItem) {
    super.addFileTransferDataItem(fileTransferDataItem);
    return this;
  }

  public MeasurementJob dataAccessEndpoint(List<DataAccessEndpoint> dataAccessEndpoint) {
    super.dataAccessEndpoint(dataAccessEndpoint);
    return this;
  }

  public MeasurementJob addDataAccessEndpointItem(DataAccessEndpoint dataAccessEndpointItem) {
    super.addDataAccessEndpointItem(dataAccessEndpointItem);
    return this;
  }

  public MeasurementJob jobId(String jobId) {
    super.jobId(jobId);
    return this;
  }

  public MeasurementJob jobPriority(Integer jobPriority) {
    super.jobPriority(jobPriority);
    return this;
  }

  public MeasurementJob lastModifiedTime(OffsetDateTime lastModifiedTime) {
    super.lastModifiedTime(lastModifiedTime);
    return this;
  }

  public MeasurementJob scheduleDefinition(List<ScheduleDefinition> scheduleDefinition) {
    super.scheduleDefinition(scheduleDefinition);
    return this;
  }

  public MeasurementJob addScheduleDefinitionItem(ScheduleDefinition scheduleDefinitionItem) {
    super.addScheduleDefinitionItem(scheduleDefinitionItem);
    return this;
  }
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    MeasurementJob measurementJob = (MeasurementJob) o;
    return Objects.equals(this.consumingApplicationId, measurementJob.consumingApplicationId) &&
        Objects.equals(this.producingApplicationId, measurementJob.producingApplicationId) &&
        Objects.equals(this.granularity, measurementJob.granularity) &&
        Objects.equals(this.performanceIndicatorGroupSpecification, measurementJob.performanceIndicatorGroupSpecification) &&
        Objects.equals(this.performanceIndicatorSpecification, measurementJob.performanceIndicatorSpecification) &&
        Objects.equals(this.trackingRecord, measurementJob.trackingRecord) &&
        Objects.equals(this.monitoredInstancesCriteria, measurementJob.monitoredInstancesCriteria) &&
        Objects.equals(this.monitoredClassCriteria, measurementJob.monitoredClassCriteria) &&
        super.equals(o);
  }

  @Override
  public int hashCode() {
    return Objects.hash(consumingApplicationId, producingApplicationId, granularity, performanceIndicatorGroupSpecification, performanceIndicatorSpecification, trackingRecord, monitoredInstancesCriteria, monitoredClassCriteria, super.hashCode());
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class MeasurementJob {\n");
    sb.append("    ").append(toIndentedString(super.toString())).append("\n");
    sb.append("    consumingApplicationId: ").append(toIndentedString(consumingApplicationId)).append("\n");
    sb.append("    producingApplicationId: ").append(toIndentedString(producingApplicationId)).append("\n");
    sb.append("    granularity: ").append(toIndentedString(granularity)).append("\n");
    sb.append("    performanceIndicatorGroupSpecification: ").append(toIndentedString(performanceIndicatorGroupSpecification)).append("\n");
    sb.append("    performanceIndicatorSpecification: ").append(toIndentedString(performanceIndicatorSpecification)).append("\n");
    sb.append("    trackingRecord: ").append(toIndentedString(trackingRecord)).append("\n");
    sb.append("    monitoredInstancesCriteria: ").append(toIndentedString(monitoredInstancesCriteria)).append("\n");
    sb.append("    monitoredClassCriteria: ").append(toIndentedString(monitoredClassCriteria)).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    ");
  }
}

