package io.delphiplatform.api.v3.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import org.openapitools.jackson.nullable.JsonNullable;

import java.net.URI;
import java.util.Objects;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import io.delphiplatform.api.util.model.ModelUtils;
import io.delphiplatform.api.v3.rdb.entity.ChartEntity;
import io.delphiplatform.api.v3.rdb.entity.ChartProjection;

/**
 * Chart
 */
@JsonPropertyOrder(alphabetic = true)
public class Chart {

    @JsonProperty("name")
    private String name;

    @JsonProperty("chart_id")
    private String chartId;

    @JsonProperty("chart_group")
    private String chartGroup;

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

    @JsonProperty("country_code")
    private String countryCode;

    @JsonProperty("rank")
    private JsonNullable<Integer> rank = JsonNullable.of(null);

    @JsonProperty("dsp")
    private Dsp dsp;

    @JsonProperty("uri")
    private JsonNullable<URI> uri = JsonNullable.undefined();

    public static Chart from(ChartEntity chart) {
        if (chart == null) {
            return null;
        }
        return new Chart()
            .chartGroup(chart.getChartGroup())
            .chartId(chart.getChartId())
            .countryCode(chart.getCountryCode() == null ? null : chart.getCountryCode().getCountryCode())
            .dsp(Dsp.from(chart.getDsp()))
            .name(chart.getName())
            .numTracks(chart.getNumTracks())
            .uri(ModelUtils.createUri(chart.getUri()));
    }

    public static Chart from(ChartProjection chart) {
        if (chart == null) {
            return null;
        }
        return new Chart()
            .chartGroup(chart.getChartGroup())
            .chartId(chart.getChartId())
            .countryCode(chart.getCountryCodeValue())
            .dsp(new Dsp()
                .dspId(chart.getDspId())
                .name(chart.getDspName())
                .slug(chart.getDspSlug()))
            .name(chart.getName())
            .numTracks(chart.getNumTracks())
            .uri(ModelUtils.createUri(chart.getUri()));
    }

    public Chart name(String name) {
        this.name = name;
        return this;
    }

    /**
     * Get name
     *
     * @return name
     */
    @NotNull
    public String getName() {
        return name;
    }

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

    public Chart chartId(String chartId) {
        this.chartId = chartId;
        return this;
    }

    /**
     * Primary key identifier for Chart
     *
     * @return chartId
     */
    @NotNull
    public String getChartId() {
        return chartId;
    }

    public void setChartId(String chartId) {
        this.chartId = chartId;
    }

    public Chart chartGroup(String chartGroup) {
        this.chartGroup = chartGroup;
        return this;
    }

    /**
     * Portion of chart primary key describing a general group the chart may belong to
     *
     * @return chartGroup
     */
    public String getChartGroup() {
        return chartGroup;
    }

    public void setChartGroup(String chartGroup) {
        this.chartGroup = chartGroup;
    }

    public Chart numTracks(Integer numTracks) {
        this.numTracks = JsonNullable.of(numTracks);
        return this;
    }

    /**
     * Total number of tracks in the chart
     *
     * @return numTracks
     */
    public JsonNullable<Integer> getNumTracks() {
        return numTracks;
    }

    public void setNumTracks(JsonNullable<Integer> numTracks) {
        this.numTracks = numTracks;
    }

    public Chart countryCode(String countryCode) {
        this.countryCode = countryCode;
        return this;
    }

    /**
     * Typically a lower-case two letter code for the country
     *
     * @return countryCode
     */
    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }

    /**
     * DEPRECATED SME internal ranking latest for global region
     *
     * @return rank
     */
    public JsonNullable<Integer> getRank() {
        return rank;
    }

    public JsonNullable<URI> getUri() {
        return uri;
    }

    public void setUri(JsonNullable<URI> uri) {
        this.uri = uri;
    }

    public Chart uri(URI uri) {
        this.uri = JsonNullable.of(uri);
        return this;
    }


    public Chart dsp(Dsp dsp) {
        this.dsp = dsp;
        return this;
    }

    /**
     * Get dsp
     *
     * @return dsp
     */
    @Valid
    public Dsp getDsp() {
        return dsp;
    }

    public void setDsp(Dsp dsp) {
        this.dsp = dsp;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Chart chart = (Chart) o;
        return Objects.equals(this.name, chart.name) &&
            Objects.equals(this.chartId, chart.chartId) &&
            Objects.equals(this.chartGroup, chart.chartGroup) &&
            Objects.equals(this.numTracks, chart.numTracks) &&
            Objects.equals(this.countryCode, chart.countryCode) &&
            Objects.equals(this.rank, chart.rank) &&
            Objects.equals(this.dsp, chart.dsp);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, chartId, chartGroup, numTracks, countryCode, rank, dsp);
    }

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

        sb.append("    name: ").append(toIndentedString(name)).append("\n");
        sb.append("    chartId: ").append(toIndentedString(chartId)).append("\n");
        sb.append("    chartGroup: ").append(toIndentedString(chartGroup)).append("\n");
        sb.append("    numTracks: ").append(toIndentedString(numTracks)).append("\n");
        sb.append("    countryCode: ").append(toIndentedString(countryCode)).append("\n");
        sb.append("    rank: ").append(toIndentedString(rank)).append("\n");
        sb.append("    dsp: ").append(toIndentedString(dsp)).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    ");
    }
}
