package com.atlassian.bitbucket.mesh.git.rebase;

import com.atlassian.bitbucket.mesh.git.AbstractParameters;
import com.atlassian.bitbucket.mesh.git.ref.Branch;
import com.atlassian.bitbucket.mesh.repository.Repository;
import com.atlassian.bitbucket.mesh.util.Person;

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

import static com.google.common.base.MoreObjects.firstNonNull;
import static java.util.Objects.requireNonNull;

public class RebaseParameters extends AbstractParameters {

    private final boolean allowEmpty;
    private final Branch branch;
    private final Person committer;
    private final Repository repository;
    private final String upstream;
    private final Repository upstreamRepository;

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

        allowEmpty = builder.allowEmpty;
        branch = requireNonNull(builder.branch, "branch");
        committer = requireNonNull(builder.committer, "committer");
        repository = requireNonNull(builder.repository, "repository");
        upstream = requireNonNull(builder.upstream, "upstream");
        upstreamRepository = firstNonNull(builder.upstreamRepository, builder.repository);
    }

    @Nonnull
    public Branch getBranch() {
        return branch;
    }

    @Nonnull
    public Person getCommitter() {
        return committer;
    }

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

    @Nonnull
    public String getUpstream() {
        return upstream;
    }

    @Nonnull
    public Repository getUpstreamRepository() {
        return upstreamRepository;
    }

    public boolean isAllowEmpty() {
        return allowEmpty;
    }

    public boolean isCrossRepository() {
        return !Objects.equals(repository, upstreamRepository);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder()
                .append(repository)
                .append(isCrossRepository() ? ":" : " ")
                .append(branch.getId())
                .append(" from ");
        if (isCrossRepository()) {
            builder.append(upstreamRepository)
                    .append(":");
        }
        builder.append(upstream);

        return builder.toString();
    }

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

        private final Repository repository;

        private boolean allowEmpty;
        private Branch branch;
        private Person committer;
        private String upstream;
        private Repository upstreamRepository;

        public Builder(@Nonnull Repository repository) {
            this.repository = requireNonNull(repository, "repository");
        }

        @Nonnull
        public Builder allowEmpty(boolean value) {
            allowEmpty = value;

            return this;
        }

        @Nonnull
        public Builder branch(@Nonnull Branch value) {
            branch = requireNonNull(value, "branch");

            return this;
        }

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

        @Nonnull
        public Builder committer(@Nonnull Person value) {
            committer = requireNonNull(value, "committer");

            return this;
        }

        @Nonnull
        public Builder upstream(@Nonnull String value) {
            upstream = requireNonNull(value, "upstream");

            return this;
        }

        @Nonnull
        public Builder upstreamRepository(@Nonnull Repository value) {
            upstreamRepository = value;

            return this;
        }

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