package ru.yandex.qe.dispenser.ws.base_resources.model;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import ru.yandex.qe.dispenser.api.v1.DiBotBigOrder;
import ru.yandex.qe.dispenser.api.v1.DiCampaign;
import ru.yandex.qe.dispenser.api.v1.DiResource;
import ru.yandex.qe.dispenser.api.v1.DiSegment;
import ru.yandex.qe.dispenser.api.v1.DiService;

@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel("Page of base resource mappings")
public final class BaseResourceMappingsPageDto {

    private final List<BaseResourceMappingDto> mappings;
    private final Map<Long, BaseResourceDto> baseResources;
    private final Map<Long, BaseResourceTypeDto> baseResourceTypes;
    private final Map<Long, DiService> providers;
    private final Map<Long, DiCampaign> campaigns;
    private final Map<Long, DiBotBigOrder> bigOrders;
    private final Map<Long, DiSegment> segments;
    private final Map<Long, DiResource> resources;
    private final Long nextFrom;

    @JsonCreator
    public BaseResourceMappingsPageDto(@JsonProperty("mappings") List<BaseResourceMappingDto> mappings,
                                       @JsonProperty("baseResources") Map<Long, BaseResourceDto> baseResources,
                                       @JsonProperty("baseResourceTypes") Map<Long, BaseResourceTypeDto> baseResourceTypes,
                                       @JsonProperty("providers") Map<Long, DiService> providers,
                                       @JsonProperty("campaigns") Map<Long, DiCampaign> campaigns,
                                       @JsonProperty("bigOrders") Map<Long, DiBotBigOrder> bigOrders,
                                       @JsonProperty("segments") Map<Long, DiSegment> segments,
                                       @JsonProperty("resources") Map<Long, DiResource> resources,
                                       @JsonProperty("nextFrom") Long nextFrom) {
        this.mappings = mappings;
        this.baseResources = baseResources;
        this.baseResourceTypes = baseResourceTypes;
        this.providers = providers;
        this.campaigns = campaigns;
        this.bigOrders = bigOrders;
        this.segments = segments;
        this.resources = resources;
        this.nextFrom = nextFrom;
    }

    @ApiModelProperty("Base resource mappings list")
    public List<BaseResourceMappingDto> getMappings() {
        return mappings;
    }

    @ApiModelProperty("Base resources referenced by mappings, indexed by base resource id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, BaseResourceDto> getBaseResources() {
        return baseResources;
    }

    @ApiModelProperty("Base resource types referenced by base resources, indexed by base resource type id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, BaseResourceTypeDto> getBaseResourceTypes() {
        return baseResourceTypes;
    }

    @ApiModelProperty("Referenced providers, indexed by id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, DiService> getProviders() {
        return providers;
    }

    @ApiModelProperty("Referenced campaigns, indexed by id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, DiCampaign> getCampaigns() {
        return campaigns;
    }

    @ApiModelProperty("Referenced big orders, indexed by id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, DiBotBigOrder> getBigOrders() {
        return bigOrders;
    }

    @ApiModelProperty("Referenced segments, indexed by id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, DiSegment> getSegments() {
        return segments;
    }

    @ApiModelProperty("Referenced resources, indexed by id")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Map<Long, DiResource> getResources() {
        return resources;
    }

    @ApiModelProperty("Id of the last base resource mapping on the page, use it to load the next page")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public Optional<Long> getNextFrom() {
        return Optional.ofNullable(nextFrom);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        BaseResourceMappingsPageDto that = (BaseResourceMappingsPageDto) o;
        return Objects.equals(mappings, that.mappings) &&
                Objects.equals(baseResources, that.baseResources) &&
                Objects.equals(baseResourceTypes, that.baseResourceTypes) &&
                Objects.equals(providers, that.providers) &&
                Objects.equals(campaigns, that.campaigns) &&
                Objects.equals(bigOrders, that.bigOrders) &&
                Objects.equals(segments, that.segments) &&
                Objects.equals(resources, that.resources) &&
                Objects.equals(nextFrom, that.nextFrom);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mappings, baseResources, baseResourceTypes, providers, campaigns, bigOrders, segments,
                resources, nextFrom);
    }

    @Override
    public String toString() {
        return "BaseResourceMappingsPageDto{" +
                "mappings=" + mappings +
                ", baseResources=" + baseResources +
                ", baseResourceTypes=" + baseResourceTypes +
                ", providers=" + providers +
                ", campaigns=" + campaigns +
                ", bigOrders=" + bigOrders +
                ", segments=" + segments +
                ", resources=" + resources +
                ", nextFrom=" + nextFrom +
                '}';
    }

}
