package ru.yandex.qe.dispenser.domain.abc;

import java.util.Objects;

import javax.annotation.ParametersAreNonnullByDefault;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.Nullable;

@ParametersAreNonnullByDefault
public class ResourcesRequestBody {
    private final long service;
    private final long resourceType;
    private final Data data;

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

    @JsonCreator
    public ResourcesRequestBody(@JsonProperty("service") final long service,
                                @JsonProperty("resource_type") final long resourceType,
                                @JsonProperty("data") final Data data) {
        this.service = service;
        this.resourceType = resourceType;
        this.data = data;
    }

    private ResourcesRequestBody(final Builder builder) {
        this.service = Objects.requireNonNull(builder.service);
        this.resourceType = Objects.requireNonNull(builder.resourceType);
        this.data = Objects.requireNonNull(builder.data);
    }

    @JsonProperty("service")
    public long getService() {
        return service;
    }

    @JsonProperty("resource_type")
    public long getResourceType() {
        return resourceType;
    }

    @JsonProperty("data")
    public Data getData() {
        return data;
    }

    public static class Builder {
        @Nullable private Long service;
        @Nullable private Long resourceType;
        @Nullable private Data data;

        public Builder service(@Nullable final Long service) {
            this.service = service;
            return this;
        }

        public Builder resourceType(@Nullable final Long resourceType) {
            this.resourceType = resourceType;
            return this;
        }

        public Builder data(@Nullable final Data data) {
            this.data = data;
            return this;
        }

        public ResourcesRequestBody build() {
            return new ResourcesRequestBody(this);
        }
    }

    public static class Data {
        private final String description;
        private final String location;
        private final String segment;
        private final double cpu;
        private final double memory;
        private final double hdd;
        private final double ioHdd;
        private final double ssd;
        private final double ioSsd;

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

        @SuppressWarnings("ConstructorWithTooManyParameters")
        @JsonCreator
        public Data(@JsonProperty("description") final String description,
                    @JsonProperty("location") final String location,
                    @JsonProperty("segment") final String segment,
                    @JsonProperty("cpu") final double cpu,
                    @JsonProperty("memory") final double memory,
                    @JsonProperty("hdd") final double hdd,
                    @JsonProperty("io_hdd") final double ioHdd,
                    @JsonProperty("ssd") final double ssd,
                    @JsonProperty("io_ssd") final double ioSsd) {
            this.description = description;
            this.location = location;
            this.segment = segment;
            this.cpu = cpu;
            this.memory = memory;
            this.hdd = hdd;
            this.ioHdd = ioHdd;
            this.ssd = ssd;
            this.ioSsd = ioSsd;
        }

        private Data(final Builder builder) {
            this.description = Objects.requireNonNull(builder.description);
            this.location = Objects.requireNonNull(builder.location);
            this.segment = Objects.requireNonNull(builder.segment);
            this.cpu = Objects.requireNonNull(builder.cpu);
            this.memory = Objects.requireNonNull(builder.memory);
            this.hdd = Objects.requireNonNull(builder.hdd);
            this.ioHdd = Objects.requireNonNull(builder.ioHdd);
            this.ssd = Objects.requireNonNull(builder.ssd);
            this.ioSsd = Objects.requireNonNull(builder.ioSsd);

        }

        @JsonProperty("description")
        public String getDescription() {
            return description;
        }

        @JsonProperty("location")
        public String getLocation() {
            return location;
        }

        @JsonProperty("segment")
        public String getSegment() {
            return segment;
        }

        @JsonProperty("cpu")
        public double getCpu() {
            return cpu;
        }

        @JsonProperty("memory")
        public double getMemory() {
            return memory;
        }

        @JsonProperty("hdd")
        public double getHdd() {
            return hdd;
        }

        @JsonProperty("io_hdd")
        public double getIoHdd() {
            return ioHdd;
        }

        @JsonProperty("ssd")
        public double getSsd() {
            return ssd;
        }

        @JsonProperty("io_ssd")
        public double getIoSsd() {
            return ioSsd;
        }

        public static class Builder {
            @Nullable private String description;
            @Nullable private String location;
            @Nullable private String segment;
            @Nullable private Double cpu;
            @Nullable private Double memory;
            @Nullable private Double hdd;
            @Nullable private Double ioHdd;
            @Nullable private Double ssd;
            @Nullable private Double ioSsd;

            public Builder description(@Nullable final String description) {
                this.description = description;
                return this;
            }

            public Builder location(@Nullable final String location) {
                this.location = location;
                return this;
            }

            public Builder segment(@Nullable final String segment) {
                this.segment = segment;
                return this;
            }

            public Builder cpu(@Nullable final Double cpu) {
                this.cpu = cpu;
                return this;
            }

            public Builder memory(@Nullable final Double memory) {
                this.memory = memory;
                return this;
            }

            public Builder hdd(@Nullable final Double hdd) {
                this.hdd = hdd;
                return this;
            }

            public Builder ioHdd(@Nullable final Double ioHdd) {
                this.ioHdd = ioHdd;
                return this;
            }

            public Builder ssd(@Nullable final Double ssd) {
                this.ssd = ssd;
                return this;
            }

            public Builder ioSsd(@Nullable final Double ioSsd) {
                this.ioSsd = ioSsd;
                return this;
            }

            public Data build() {
                return new Data(this);
            }
        }
    }
}
