package com.atlassian.stash.internal.scm.git.porcelain;

import com.atlassian.bitbucket.repository.Repository;
import com.google.common.collect.ImmutableSet;

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

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

/**
 * @since 2.9
 */
public class WorkTreeRequest extends AbstractTimedRequest {

    private final Set<Repository> alternates;
    private final String branch;
    private final String commit;
    private final Repository repository;

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

        alternates = builder.alternates.build();
        branch = builder.branch;
        commit = builder.commit;
        repository = builder.repository;
    }

    @Nonnull
    public Set<Repository> getAlternates() {
        return alternates;
    }

    @Nullable
    public String getBranch() {
        return branch;
    }

    @Nonnull
    public String getCommit() {
        return commit;
    }

    @Nonnull
    public Repository getRepository() {
        return repository;
    }

    public boolean hasBranch() {
        return branch != null;
    }

    public boolean hasCommit() {
        return commit != null;
    }

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

        private final ImmutableSet.Builder<Repository> alternates;
        private final String commit;
        private final Repository repository;

        private String branch;

        public Builder(@Nonnull Repository repository, @Nonnull String commit) {
            this.repository = checkNotNull(repository, "repository");
            this.commit = checkNotBlank(commit, "commit");

            alternates = ImmutableSet.builder();
        }

        public Builder(WorkTreeRequest request) {
            super(request);

            alternates = ImmutableSet.<Repository>builder().addAll(request.getAlternates());
            commit = request.getCommit();
            repository = request.getRepository();
        }

        @Nonnull
        public Builder alternate(@Nonnull Repository value) {
            alternates.add(value);

            return self();
        }

        @Nonnull
        public Builder alternates(@Nonnull Iterable<Repository> values) {
            alternates.addAll(values);

            return self();
        }

        @Nonnull
        public Builder alternates(@Nonnull Repository value, Repository... values) {
            alternates.add(value).add(values);

            return self();
        }

        @Nonnull
        public Builder branch(@Nullable String value) {
            branch = value;

            return self();
        }

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

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