package ru.yandex.qe.dispenser.domain.dictionaries.model;

import java.util.Objects;
import java.util.Set;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public final class FrontDictionaries {

    public static final String REQUEST_STATUS = "REQUEST_STATUS";
    public static final String REQUEST_REASON = "REQUEST_REASON";
    public static final String PROVIDERS_WITH_CAMPAIGNS = "PROVIDERS_WITH_CAMPAIGNS";
    public static final String CAMPAIGNS_WITH_BIG_ORDERS = "CAMPAIGNS_WITH_BIG_ORDERS";
    public static final String SORT_FIELDS = "SORT_FIELDS";
    public static final String CAMPAIGN_PROVIDERS_SETTINGS = "CAMPAIGN_PROVIDERS_SETTINGS";
    public static final String RESOURCES_WITH_CAMPAIGNS = "RESOURCES_WITH_CAMPAIGNS";
    public static final String SEGMENTATIONS_WITH_CAMPAIGNS = "SEGMENTATIONS_WITH_CAMPAIGNS";
    public static final String UNITS = "UNITS";
    public static final String RESOURCES_WITH_UNIT_ALIASES = "RESOURCES_WITH_UNIT_ALIASES";

    public static final Set<String> VALID_DICTIONARIES = ImmutableSet.of(REQUEST_STATUS, REQUEST_REASON,
            PROVIDERS_WITH_CAMPAIGNS, CAMPAIGNS_WITH_BIG_ORDERS, SORT_FIELDS, CAMPAIGN_PROVIDERS_SETTINGS,
            RESOURCES_WITH_CAMPAIGNS, SEGMENTATIONS_WITH_CAMPAIGNS, UNITS, RESOURCES_WITH_UNIT_ALIASES);

    @Nullable
    private final RequestStatusesDictionary requestStatusesDictionary;
    @Nullable
    private final RequestReasonsDictionary requestReasonsDictionary;
    @Nullable
    private final ProvidersWithCampaignsDictionary providersWithCampaignsDictionary;
    @Nullable
    private final CampaignsWithBigOrdersDictionary campaignsWithBigOrdersDictionary;
    @Nullable
    private final SortFieldsDictionary sortFieldsDictionary;
    @Nullable
    private final CampaignProvidersSettingsDictionary campaignProvidersSettingsDictionary;
    @Nullable
    private final ResourcesWithCampaignsDictionary resourcesWithCampaignsDictionary;
    @Nullable
    private final SegmentationsWithCampaignsDictionary segmentationsWithCampaignsDictionary;
    @Nullable
    private final UnitsDictionary unitsDictionary;
    @Nullable
    private final ResourcesWithUnitAliasesDictionary resourcesWithUnitAliasesDictionary;

    @JsonCreator
    public FrontDictionaries(@Nullable @JsonProperty(REQUEST_STATUS) final RequestStatusesDictionary requestStatusesDictionary,
                             @Nullable @JsonProperty(REQUEST_REASON) final RequestReasonsDictionary requestReasonsDictionary,
                             @Nullable @JsonProperty(PROVIDERS_WITH_CAMPAIGNS) final ProvidersWithCampaignsDictionary providersWithCampaignsDictionary,
                             @Nullable @JsonProperty(CAMPAIGNS_WITH_BIG_ORDERS) final CampaignsWithBigOrdersDictionary campaignsWithBigOrdersDictionary,
                             @Nullable @JsonProperty(SORT_FIELDS) final SortFieldsDictionary sortFieldsDictionary,
                             @Nullable @JsonProperty(CAMPAIGN_PROVIDERS_SETTINGS) final CampaignProvidersSettingsDictionary campaignProvidersSettingsDictionary,
                             @Nullable @JsonProperty(RESOURCES_WITH_CAMPAIGNS) final ResourcesWithCampaignsDictionary resourcesWithCampaignsDictionary,
                             @Nullable @JsonProperty(SEGMENTATIONS_WITH_CAMPAIGNS) final SegmentationsWithCampaignsDictionary segmentationsWithCampaignsDictionary,
                             @Nullable @JsonProperty(UNITS) final UnitsDictionary unitsDictionary,
                             @Nullable @JsonProperty(RESOURCES_WITH_UNIT_ALIASES) final ResourcesWithUnitAliasesDictionary resourcesWithUnitAliasesDictionary) {
        this.requestStatusesDictionary = requestStatusesDictionary;
        this.requestReasonsDictionary = requestReasonsDictionary;
        this.providersWithCampaignsDictionary = providersWithCampaignsDictionary;
        this.campaignsWithBigOrdersDictionary = campaignsWithBigOrdersDictionary;
        this.sortFieldsDictionary = sortFieldsDictionary;
        this.campaignProvidersSettingsDictionary = campaignProvidersSettingsDictionary;
        this.resourcesWithCampaignsDictionary = resourcesWithCampaignsDictionary;
        this.segmentationsWithCampaignsDictionary = segmentationsWithCampaignsDictionary;
        this.unitsDictionary = unitsDictionary;
        this.resourcesWithUnitAliasesDictionary = resourcesWithUnitAliasesDictionary;
    }

    @NotNull
    public static Builder builder() {
        return new Builder();
    }

    @Nullable
    @JsonProperty(REQUEST_STATUS)
    public RequestStatusesDictionary getRequestStatusesDictionary() {
        return requestStatusesDictionary;
    }

    @Nullable
    @JsonProperty(REQUEST_REASON)
    public RequestReasonsDictionary getRequestReasonsDictionary() {
        return requestReasonsDictionary;
    }

    @Nullable
    @JsonProperty(PROVIDERS_WITH_CAMPAIGNS)
    public ProvidersWithCampaignsDictionary getProvidersWithCampaignsDictionary() {
        return providersWithCampaignsDictionary;
    }

    @Nullable
    @JsonProperty(CAMPAIGNS_WITH_BIG_ORDERS)
    public CampaignsWithBigOrdersDictionary getCampaignsWithBigOrdersDictionary() {
        return campaignsWithBigOrdersDictionary;
    }

    @Nullable
    @JsonProperty(SORT_FIELDS)
    public SortFieldsDictionary getSortFieldsDictionary() {
        return sortFieldsDictionary;
    }

    @Nullable
    @JsonProperty(CAMPAIGN_PROVIDERS_SETTINGS)
    public CampaignProvidersSettingsDictionary getCampaignProvidersSettingsDictionary() {
        return campaignProvidersSettingsDictionary;
    }

    @Nullable
    @JsonProperty(RESOURCES_WITH_CAMPAIGNS)
    public ResourcesWithCampaignsDictionary getResourcesWithCampaignsDictionary() {
        return resourcesWithCampaignsDictionary;
    }

    @Nullable
    @JsonProperty(SEGMENTATIONS_WITH_CAMPAIGNS)
    public SegmentationsWithCampaignsDictionary getSegmentationsWithCampaignsDictionary() {
        return segmentationsWithCampaignsDictionary;
    }

    @Nullable
    @JsonProperty(UNITS)
    public UnitsDictionary getUnitsDictionary() {
        return unitsDictionary;
    }

    @Nullable
    @JsonProperty(RESOURCES_WITH_UNIT_ALIASES)
    public ResourcesWithUnitAliasesDictionary getResourcesWithUnitAliasesDictionary() {
        return resourcesWithUnitAliasesDictionary;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final FrontDictionaries that = (FrontDictionaries) o;
        return Objects.equals(requestStatusesDictionary, that.requestStatusesDictionary) &&
                Objects.equals(requestReasonsDictionary, that.requestReasonsDictionary) &&
                Objects.equals(providersWithCampaignsDictionary, that.providersWithCampaignsDictionary) &&
                Objects.equals(campaignsWithBigOrdersDictionary, that.campaignsWithBigOrdersDictionary) &&
                Objects.equals(sortFieldsDictionary, that.sortFieldsDictionary) &&
                Objects.equals(campaignProvidersSettingsDictionary, that.campaignProvidersSettingsDictionary) &&
                Objects.equals(resourcesWithCampaignsDictionary, that.resourcesWithCampaignsDictionary) &&
                Objects.equals(segmentationsWithCampaignsDictionary, that.segmentationsWithCampaignsDictionary) &&
                Objects.equals(unitsDictionary, that.unitsDictionary) &&
                Objects.equals(resourcesWithUnitAliasesDictionary, that.resourcesWithUnitAliasesDictionary);
    }

    @Override
    public int hashCode() {
        return Objects.hash(requestStatusesDictionary, requestReasonsDictionary, providersWithCampaignsDictionary, campaignsWithBigOrdersDictionary, sortFieldsDictionary, campaignProvidersSettingsDictionary, resourcesWithCampaignsDictionary, segmentationsWithCampaignsDictionary, unitsDictionary, resourcesWithUnitAliasesDictionary);
    }

    @Override
    public String toString() {
        return "FrontDictionaries{" +
                "requestStatusesDictionary=" + requestStatusesDictionary +
                ", requestReasonsDictionary=" + requestReasonsDictionary +
                ", providersWithCampaignsDictionary=" + providersWithCampaignsDictionary +
                ", campaignsWithBigOrdersDictionary=" + campaignsWithBigOrdersDictionary +
                ", sortFieldsDictionary=" + sortFieldsDictionary +
                ", campaignProvidersSettingsDictionary=" + campaignProvidersSettingsDictionary +
                ", resourcesWithCampaignsDictionary=" + resourcesWithCampaignsDictionary +
                ", segmentationsWithCampaignsDictionary=" + segmentationsWithCampaignsDictionary +
                ", unitsDictionary=" + unitsDictionary +
                ", resourcesWithUnitAliasesDictionary=" + resourcesWithUnitAliasesDictionary +
                '}';
    }

    public static final class Builder {

        @Nullable
        private RequestStatusesDictionary requestStatusesDictionary;
        @Nullable
        private RequestReasonsDictionary requestReasonsDictionary;
        @Nullable
        private ProvidersWithCampaignsDictionary providersWithCampaignsDictionary;
        @Nullable
        private CampaignsWithBigOrdersDictionary campaignsWithBigOrdersDictionary;
        @Nullable
        private SortFieldsDictionary sortFieldsDictionary;
        @Nullable
        private CampaignProvidersSettingsDictionary campaignProvidersSettingsDictionary;
        @Nullable
        private ResourcesWithCampaignsDictionary resourcesWithCampaignsDictionary;
        @Nullable
        private SegmentationsWithCampaignsDictionary segmentationsWithCampaignsDictionary;
        @Nullable
        private UnitsDictionary unitsDictionary;
        @Nullable
        private ResourcesWithUnitAliasesDictionary resourcesWithUnitAliasesDictionary;

        private Builder() {
        }

        @NotNull
        public Builder requestStatusesDictionary(
                @NotNull final RequestStatusesDictionary requestStatusesDictionary) {
            Objects.requireNonNull(requestStatusesDictionary, "Request statuses dictionary is required.");
            this.requestStatusesDictionary = requestStatusesDictionary;
            return this;
        }

        @NotNull
        public Builder requestReasonsDictionary(
                @NotNull final RequestReasonsDictionary requestReasonsDictionary) {
            Objects.requireNonNull(requestReasonsDictionary, "Request reasons dictionary is required.");
            this.requestReasonsDictionary = requestReasonsDictionary;
            return this;
        }

        @NotNull
        public Builder providersWithCampaignsDictionary(
                @NotNull final ProvidersWithCampaignsDictionary providersWithCampaignsDictionary) {
            Objects.requireNonNull(providersWithCampaignsDictionary, "Providers with campaigns dictionary is required.");
            this.providersWithCampaignsDictionary = providersWithCampaignsDictionary;
            return this;
        }

        @NotNull
        public Builder campaignsWithBigOrdersDictionary(
                @NotNull final CampaignsWithBigOrdersDictionary campaignsWithBigOrdersDictionary) {
            Objects.requireNonNull(campaignsWithBigOrdersDictionary, "Campaigns with big orders dictionary is required.");
            this.campaignsWithBigOrdersDictionary = campaignsWithBigOrdersDictionary;
            return this;
        }

        @NotNull
        public Builder sortFieldsDictionary(
                @NotNull final SortFieldsDictionary sortFieldsDictionary) {
            Objects.requireNonNull(sortFieldsDictionary, "Sort fields dictionary is required.");
            this.sortFieldsDictionary = sortFieldsDictionary;
            return this;
        }

        @NotNull
        public Builder campaignProvidersSettingsDictionary(
                @NotNull final CampaignProvidersSettingsDictionary campaignProvidersSettingsDictionary) {
            Objects.requireNonNull(campaignProvidersSettingsDictionary, "Campaign providers settings dictionary is required.");
            this.campaignProvidersSettingsDictionary = campaignProvidersSettingsDictionary;
            return this;
        }

        @NotNull
        public Builder resourcesWithCampaignsDictionary(
                @NotNull final ResourcesWithCampaignsDictionary resourcesWithCampaignsDictionary) {
            Objects.requireNonNull(resourcesWithCampaignsDictionary, "Resources with campaigns dictionary ir required.");
            this.resourcesWithCampaignsDictionary = resourcesWithCampaignsDictionary;
            return this;
        }

        @NotNull
        public Builder segmentationsWithCampaignsDictionary(
                @NotNull final SegmentationsWithCampaignsDictionary segmentationsWithCampaignsDictionary) {
            Objects.requireNonNull(segmentationsWithCampaignsDictionary, "Segmentations with campaigns dictionary is required.");
            this.segmentationsWithCampaignsDictionary = segmentationsWithCampaignsDictionary;
            return this;
        }

        @NotNull
        public Builder unitsDictionary(final UnitsDictionary unitsDictionary) {
            Objects.requireNonNull(unitsDictionary, "Units dictionary is required.");
            this.unitsDictionary = unitsDictionary;
            return this;
        }

        @NotNull
        public Builder resourcesWithUnitAliasesDictionary(final ResourcesWithUnitAliasesDictionary resourcesWithUnitAliasesDictionary) {
            Objects.requireNonNull(resourcesWithUnitAliasesDictionary, "Resources with unit aliases dictionary is required.");
            this.resourcesWithUnitAliasesDictionary = resourcesWithUnitAliasesDictionary;
            return this;
        }

        @Nullable
        public RequestStatusesDictionary getRequestStatusesDictionary() {
            return requestStatusesDictionary;
        }

        @Nullable
        public RequestReasonsDictionary getRequestReasonsDictionary() {
            return requestReasonsDictionary;
        }

        @Nullable
        public ProvidersWithCampaignsDictionary getProvidersWithCampaignsDictionary() {
            return providersWithCampaignsDictionary;
        }

        @Nullable
        public CampaignsWithBigOrdersDictionary getCampaignsWithBigOrdersDictionary() {
            return campaignsWithBigOrdersDictionary;
        }

        @Nullable
        public SortFieldsDictionary getSortFieldsDictionary() {
            return sortFieldsDictionary;
        }

        @Nullable
        public CampaignProvidersSettingsDictionary getCampaignProvidersSettingsDictionary() {
            return campaignProvidersSettingsDictionary;
        }

        @Nullable
        public ResourcesWithCampaignsDictionary getResourcesWithCampaignsDictionary() {
            return resourcesWithCampaignsDictionary;
        }

        @Nullable
        public SegmentationsWithCampaignsDictionary getSegmentationsWithCampaignsDictionary() {
            return segmentationsWithCampaignsDictionary;
        }

        @NotNull
        public FrontDictionaries build() {
            return new FrontDictionaries(requestStatusesDictionary, requestReasonsDictionary,
                    providersWithCampaignsDictionary, campaignsWithBigOrdersDictionary,
                    sortFieldsDictionary, campaignProvidersSettingsDictionary, resourcesWithCampaignsDictionary,
                    segmentationsWithCampaignsDictionary, unitsDictionary, resourcesWithUnitAliasesDictionary);
        }

        @Override
        public boolean equals(final Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            final Builder builder = (Builder) o;
            return Objects.equals(requestStatusesDictionary, builder.requestStatusesDictionary) &&
                    Objects.equals(requestReasonsDictionary, builder.requestReasonsDictionary) &&
                    Objects.equals(providersWithCampaignsDictionary, builder.providersWithCampaignsDictionary) &&
                    Objects.equals(campaignsWithBigOrdersDictionary, builder.campaignsWithBigOrdersDictionary) &&
                    Objects.equals(sortFieldsDictionary, builder.sortFieldsDictionary) &&
                    Objects.equals(campaignProvidersSettingsDictionary, builder.campaignProvidersSettingsDictionary) &&
                    Objects.equals(resourcesWithCampaignsDictionary, builder.resourcesWithCampaignsDictionary) &&
                    Objects.equals(segmentationsWithCampaignsDictionary, builder.segmentationsWithCampaignsDictionary);
        }

        @Override
        public int hashCode() {
            return Objects.hash(requestStatusesDictionary, requestReasonsDictionary, providersWithCampaignsDictionary,
                    campaignsWithBigOrdersDictionary, sortFieldsDictionary, campaignProvidersSettingsDictionary,
                    resourcesWithCampaignsDictionary, segmentationsWithCampaignsDictionary);
        }

        @Override
        public String toString() {
            return "Builder{" +
                    "requestStatusesDictionary=" + requestStatusesDictionary +
                    ", requestReasonsDictionary=" + requestReasonsDictionary +
                    ", providersWithCampaignsDictionary=" + providersWithCampaignsDictionary +
                    ", campaignsWithBigOrdersDictionary=" + campaignsWithBigOrdersDictionary +
                    ", sortFieldsDictionary=" + sortFieldsDictionary +
                    ", campaignProvidersSettingsDictionary=" + campaignProvidersSettingsDictionary +
                    ", resourcesWithCampaignsDictionary=" + resourcesWithCampaignsDictionary +
                    ", segmentationsWithCampaignsDictionary=" + segmentationsWithCampaignsDictionary +
                    '}';
        }

    }

}
