package io.delphiplatform.api.v3.model;

import com.fasterxml.jackson.annotation.JsonProperty;

import org.openapitools.jackson.nullable.JsonNullable;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;
import java.util.Objects;

import javax.validation.Valid;
import javax.validation.constraints.Pattern;

import io.delphiplatform.api.v3.constant.ApplicationConstants;

/**
 * Object containing the base details of a Track &#x60;Position&#x60;.
 */
public class BaseTrackPosition {

    @JsonProperty("isrc")
    private String isrc;

    @JsonProperty("dsp")
    private JsonNullable<String> dsp = JsonNullable.undefined();

    @JsonProperty("current")
    private JsonNullable<Integer> current = JsonNullable.undefined();

    @JsonProperty("previous")
    private JsonNullable<Integer> previous = JsonNullable.undefined();

    @JsonProperty("top")
    private JsonNullable<Integer> top = JsonNullable.undefined();

    @JsonProperty("num_weeks_on")
    private JsonNullable<Integer> numWeeksOn = JsonNullable.undefined();

    @JsonProperty("date")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    private JsonNullable<LocalDate> date = JsonNullable.undefined();

    public BaseTrackPosition isrc(String isrc) {
        this.isrc = isrc;
        return this;
    }

    /**
     * The International Standard Recording Code (ISRC) for a song.
     *
     * @return isrc
     */
    @Pattern(regexp = ApplicationConstants.ISRC_PATTERN)
    public String getIsrc() {
        return isrc;
    }

    public void setIsrc(String isrc) {
        this.isrc = isrc;
    }

    public BaseTrackPosition dsp(String dsp) {
        this.dsp = JsonNullable.of(dsp);
        return this;
    }

    /**
     * Slug name of a DSP
     *
     * @return dsp
     */
    @Pattern(regexp = "^[a-z]*$")
    public JsonNullable<String> getDsp() {
        return dsp;
    }

    public void setDsp(JsonNullable<String> dsp) {
        this.dsp = dsp;
    }

    public BaseTrackPosition current(Integer current) {
        this.current = JsonNullable.of(current);
        return this;
    }

    /**
     * Get current
     *
     * @return current
     */
    public JsonNullable<Integer> getCurrent() {
        return current;
    }

    public void setCurrent(JsonNullable<Integer> current) {
        this.current = current;
    }

    public BaseTrackPosition previous(Integer previous) {
        this.previous = JsonNullable.of(previous);
        return this;
    }

    /**
     * Get previous
     *
     * @return previous
     */
    public JsonNullable<Integer> getPrevious() {
        return previous;
    }

    public void setPrevious(JsonNullable<Integer> previous) {
        this.previous = previous;
    }

    public BaseTrackPosition top(Integer top) {
        this.top = JsonNullable.of(top);
        return this;
    }

    /**
     * Get top
     *
     * @return top
     */
    public JsonNullable<Integer> getTop() {
        return top;
    }

    public void setTop(JsonNullable<Integer> top) {
        this.top = top;
    }

    public BaseTrackPosition numWeeksOn(Integer numWeeksOn) {
        this.numWeeksOn = JsonNullable.of(numWeeksOn);
        return this;
    }

    /**
     * Get numWeeksOn
     *
     * @return numWeeksOn
     */
    public JsonNullable<Integer> getNumWeeksOn() {
        return numWeeksOn;
    }

    public void setNumWeeksOn(JsonNullable<Integer> numWeeksOn) {
        this.numWeeksOn = numWeeksOn;
    }

    public BaseTrackPosition date(LocalDate date) {
        this.date = JsonNullable.of(date);
        return this;
    }

    /**
     * ISO 8601 date in format `YYYY-MM-DD`
     *
     * @return date
     */
    @Valid
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$")
    public JsonNullable<LocalDate> getDate() {
        return date;
    }

    public void setDate(JsonNullable<LocalDate> date) {
        this.date = date;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        BaseTrackPosition baseTrackPosition = (BaseTrackPosition) o;
        return Objects.equals(this.isrc, baseTrackPosition.isrc) &&
            Objects.equals(this.dsp, baseTrackPosition.dsp) &&
            Objects.equals(this.current, baseTrackPosition.current) &&
            Objects.equals(this.previous, baseTrackPosition.previous) &&
            Objects.equals(this.top, baseTrackPosition.top) &&
            Objects.equals(this.numWeeksOn, baseTrackPosition.numWeeksOn) &&
            Objects.equals(this.date, baseTrackPosition.date);
    }

    @Override
    public int hashCode() {
        return Objects.hash(isrc, dsp, current, previous, top, numWeeksOn, date);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class BaseTrackPosition {\n");

        sb.append("    isrc: ").append(toIndentedString(isrc)).append("\n");
        sb.append("    dsp: ").append(toIndentedString(dsp)).append("\n");
        sb.append("    current: ").append(toIndentedString(current)).append("\n");
        sb.append("    previous: ").append(toIndentedString(previous)).append("\n");
        sb.append("    top: ").append(toIndentedString(top)).append("\n");
        sb.append("    numWeeksOn: ").append(toIndentedString(numWeeksOn)).append("\n");
        sb.append("    date: ").append(toIndentedString(date)).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    ");
    }
}
