package com.atlassian.bitbucket.scm;

import com.atlassian.bitbucket.content.ChangeContext;
import com.google.common.collect.ImmutableSet;

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

import static com.google.common.base.Preconditions.checkNotNull;

public class AbstractChangesCommandParameters extends AbstractCommandParameters {

    private final int maxChanges;
    private final Set<String> paths;

    protected AbstractChangesCommandParameters(int maxChanges, Set<String> paths) {
        this.maxChanges = maxChanges;
        this.paths = paths;
    }

    public int getMaxChanges() {
        return maxChanges;
    }

    @Nonnull
    public Set<String> getPaths() {
        return paths;
    }

    public boolean hasPaths() {
        return !paths.isEmpty();
    }

    /**
     * Appends common attributes to the provided {@link ChangeContext.Builder} before
     * building it and returning the final {@link ChangeContext}.
     *
     * @param builder the starting builder to apply common attributes to before building
     * @return the {@link ChangeContext} from the provided builder
     */
    @Nonnull
    protected ChangeContext toContext(@Nonnull ChangeContext.Builder builder) {
        return checkNotNull(builder, "builder").maxChanges(getMaxChanges())
                .build();
    }

    public abstract static class AbstractBuilder<B extends AbstractBuilder<B>> {

        protected final ImmutableSet.Builder<String> paths;

        protected int maxChanges;

        protected AbstractBuilder() {
            paths = ImmutableSet.builder();
        }

        public B maxChanges(int value) {
            maxChanges = value;

            return self();
        }

        public B path(String value) {
            addIf(NOT_BLANK, paths, value);

            return self();
        }

        public B paths(Iterable<String> values) {
            addIf(NOT_BLANK, paths, values);

            return self();
        }

        public B paths(String value, String... values) {
            addIf(NOT_BLANK, paths, value, values);

            return self();
        }

        protected abstract B self();
    }
}
