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.DiSegment;
import ru.yandex.qe.dispenser.api.v1.DiService;

@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel("Page of base resources")
public final class BaseResourcesPageDto {

    private final List<BaseResourceDto> resources;
    private final Map<Long, BaseResourceTypeDto> resourceTypes;
    private final Map<Long, DiSegment> segments;
    private final Map<Long, DiService> providers;
    private final Long nextFrom;

    @JsonCreator
    public BaseResourcesPageDto(@JsonProperty("resources") List<BaseResourceDto> resources,
                                @JsonProperty("resourceTypes") Map<Long, BaseResourceTypeDto> resourceTypes,
                                @JsonProperty("segments") Map<Long, DiSegment> segments,
                                @JsonProperty("providers") Map<Long, DiService> providers,
                                @JsonProperty("nextFrom") Long nextFrom) {
        this.resources = resources;
        this.resourceTypes = resourceTypes;
        this.segments = segments;
        this.providers = providers;
        this.nextFrom = nextFrom;
    }

    @ApiModelProperty("Base resource list")
    public List<BaseResourceDto> getResources() {
        return resources;
    }

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

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

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @ApiModelProperty("Providers referenced by base resource types, indexed by provider id")
    public Map<Long, DiService> getProviders() {
        return providers;
    }

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @ApiModelProperty("Id of the last base resource on the page, use it to load the next page")
    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;
        }
        BaseResourcesPageDto that = (BaseResourcesPageDto) o;
        return Objects.equals(resources, that.resources) &&
                Objects.equals(resourceTypes, that.resourceTypes) &&
                Objects.equals(segments, that.segments) &&
                Objects.equals(providers, that.providers) &&
                Objects.equals(nextFrom, that.nextFrom);
    }

    @Override
    public int hashCode() {
        return Objects.hash(resources, resourceTypes, segments, providers, nextFrom);
    }

    @Override
    public String toString() {
        return "BaseResourcesPageDto{" +
                "resources=" + resources +
                ", resourceTypes=" + resourceTypes +
                ", segments=" + segments +
                ", providers=" + providers +
                ", nextFrom=" + nextFrom +
                '}';
    }

}
