package com.atlassian.bitbucket.mesh.network;

import com.atlassian.bitbucket.mesh.util.BuilderSupport;
import com.google.common.collect.ImmutableList;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;

public class UpdateTopologyParameters {

    private final List<PartitionReplicaMigration> migrations;
    private final List<MeshNode> nodes;
    private final List<Partition> partitions;

    private UpdateTopologyParameters(Builder builder) {
        migrations = builder.migrations.build();
        nodes = builder.nodes.build();
        partitions = builder.partitions.build();
    }

    /**
     * @since 1.4
     */
    @Nonnull
    public List<PartitionReplicaMigration> getMigrations() {
        return migrations;
    }

    @Nonnull
    public List<MeshNode> getNodes() {
        return nodes;
    }

    @Nonnull
    public List<Partition> getPartitions() {
        return partitions;
    }

    public static class Builder extends BuilderSupport {

        private final ImmutableList.Builder<PartitionReplicaMigration> migrations;
        private final ImmutableList.Builder<MeshNode> nodes;
        private final ImmutableList.Builder<Partition> partitions;

        public Builder() {
            migrations = ImmutableList.builder();
            nodes = ImmutableList.builder();
            partitions = ImmutableList.builder();
        }

        @Nonnull
        public UpdateTopologyParameters build() {
            return new UpdateTopologyParameters(this);
        }

        /**
         * @since 1.4
         */
        @Nonnull
        public Builder migrations(@Nullable PartitionReplicaMigration value,
                                  @Nullable PartitionReplicaMigration... moreValues) {
            addIf(Objects::nonNull, migrations, value, moreValues);
            return this;
        }

        /**
         * @since 1.4
         */
        @Nonnull
        public Builder migrations(@Nullable Iterable<PartitionReplicaMigration> values) {
            addIf(Objects::nonNull, migrations, values);
            return this;
        }

        @Nonnull
        public Builder nodes(@Nullable MeshNode value, @Nullable MeshNode... moreValues) {
            addIf(Objects::nonNull, nodes, value, moreValues);
            return this;
        }

        @Nonnull
        public Builder nodes(@Nullable Iterable<MeshNode> values) {
            addIf(Objects::nonNull, nodes, values);
            return this;
        }

        @Nonnull
        public Builder partitions(@Nullable Partition value, @Nullable Partition... moreValues) {
            addIf(Objects::nonNull, partitions, value, moreValues);
            return this;
        }

        @Nonnull
        public Builder partitions(@Nullable Iterable<Partition> values) {
            addIf(Objects::nonNull, partitions, values);
            return this;
        }
    }
}
