package com.atlassian.bitbucket.mesh.client;

import com.atlassian.bitbucket.mesh.git.AbstractParameters;
import com.google.common.collect.ImmutableSet;

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

public class FetchObjectsParameters extends AbstractParameters {

    private final Set<String> excludes;
    private final Set<String> includes;
    private final boolean keep;

    private FetchObjectsParameters(Builder builder) {
        super(builder);

        excludes = builder.excludes.build();
        includes = builder.includes.build();
        keep = builder.keep;
    }

    @Nonnull
    public Set<String> getExcludes() {
        return excludes;
    }

    @Nonnull
    public Set<String> getIncludes() {
        return includes;
    }

    /**
     * @return {@code true} if the resulting pack should be protected from concurrent garbage collection by creating a
     *         {@code .keep} file.
     */
    public boolean isKeep() {
        return keep;
    }

    public static class Builder extends AbstractBuilder<Builder, FetchObjectsParameters> {

        private final ImmutableSet.Builder<String> excludes;
        private final ImmutableSet.Builder<String> includes;

        private boolean keep;

        public Builder() {
            excludes = ImmutableSet.builder();
            includes = ImmutableSet.builder();
        }

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

        @Nonnull
        public Builder excludes(@Nullable String value, @Nullable String... moreValues) {
            addIf(Objects::nonNull, excludes, value, moreValues);
            return self();
        }

        @Nonnull
        public Builder excludes(@Nullable Iterable<String> values) {
            addIf(Objects::nonNull, excludes, values);
            return self();
        }

        @Nonnull
        public Builder includes(@Nullable String value, @Nullable String... moreValues) {
            addIf(Objects::nonNull, includes, value, moreValues);
            return self();
        }

        @Nonnull
        public Builder includes(@Nullable Iterable<String> values) {
            addIf(Objects::nonNull, includes, values);
            return self();
        }

        @Nonnull
        public Builder keep(boolean value) {
            keep = value;
            return self();
        }

        @Nonnull
        @Override
        protected Builder self() {
            return this;
        }
    }
}
