package com.atlassian.bitbucket.scm;

import com.atlassian.bitbucket.commit.AbstractCommitRequest;
import com.atlassian.bitbucket.commit.CommitRequest;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static java.util.Objects.requireNonNull;

/**
 * A base class for constructing {@code CommandParameters} classes for commands which operate on a specific commit,
 * optionally qualified to a specific path.
 * <p>
 * What the {@link #getCommitId() commit} and {@link #getPath() path} mean to the end command may vary widely.
 * Derived classes will document those meanings. Extending from this base class implies no contract beyond that:
 * <ul>
 *     <li>The {@link #getCommitId() commit} will never be {@code null}</li>
 *     <li>The {@link #getPath() path} <i>may</i> be {@code null} <i>unless documented otherwise by the derived
 *     class</i></li>
 * </ul>
 */
public class AbstractCommitCommandParameters extends AbstractCommandParameters {

    private final String commitId;
    private final String path;

    protected AbstractCommitCommandParameters(AbstractCommitParametersBuilder<?> builder) {
        commitId = builder.commitId;
        path = builder.path;
    }

    @Nonnull
    public String getCommitId() {
        return commitId;
    }

    @Nullable
    public String getPath() {
        return path;
    }

    public boolean hasPath() {
        return StringUtils.isNotBlank(path);
    }

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

        private String commitId;
        private String path;

        protected AbstractCommitParametersBuilder() {
        }

        protected AbstractCommitParametersBuilder(@Nonnull AbstractCommitRequest request) {
            commitId = requireNonNull(request, "request").getCommitId();
            path = request.getPath();
        }

        //TODO in 5.0: Remove this constructor. It can't be done in a point release due to how Java linkage works
        protected AbstractCommitParametersBuilder(@Nonnull CommitRequest request) {
            this((AbstractCommitRequest) request);
        }

        @Nonnull
        public B commitId(String value) {
            commitId = value;

            return self();
        }

        @Nonnull
        public B path(String value) {
            path = value;

            return self();
        }

        @Nonnull
        protected abstract B self();
    }
}
