package com.atlassian.bitbucket.comment.commit;

import com.atlassian.bitbucket.comment.AbstractAddLineCommentRequest;
import com.atlassian.bitbucket.comment.DiffCommentAnchor;
import com.atlassian.bitbucket.commit.CommitDiscussionCommentAnchor;
import com.atlassian.bitbucket.repository.Repository;
import org.apache.commons.lang3.StringUtils;

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

import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;

/**
 * Request to create a {@link CommitDiscussionCommentAnchor#isLineComment() line comment}.
 *
 * @since 4.7
 */
public class AddCommitLineCommentRequest extends AbstractAddLineCommentRequest {

    private final String fromHash;
    private final Long pullRequestId;
    private final Repository repository;
    private final String toHash;

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

        fromHash = StringUtils.trimToNull(builder.fromHash);
        pullRequestId = builder.pullRequestId;
        repository = requireNonNull(builder.repository, "repository");
        toHash = requireNonNull(StringUtils.trimToNull(builder.toHash), "toHash");
    }

    /**
     * @return the {@link DiffCommentAnchor#getFromHash() from hash} to anchor the comment to. If the returned
     * {@link Optional} is empty then it will automatically inferred
     */
    @Nonnull
    public Optional<String> getFromHash() {
        return ofNullable(fromHash);
    }

    /**
     * @return the ID for a pull request the comment must be anchored to
     */
    @Nonnull
    public Optional<Long> getPullRequestId() {
        return ofNullable(pullRequestId);
    }

    /**
     * @return the repository that holds the commit the comment must be added on
     */
    @Nonnull
    public Repository getRepository() {
        return repository;
    }

    /**
     * @return the {@link DiffCommentAnchor#getToHash() to hash} to anchor the comment to
     */
    @Nonnull
    public String getToHash() {
        return toHash;
    }

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

        private final Repository repository;
        private final String toHash;

        private String fromHash;
        private Long pullRequestId;

        public Builder(@Nonnull Repository repository, @Nonnull String toHash) {
            this.repository = repository;
            this.toHash = toHash;
        }

        public Builder(@Nonnull AddCommitLineCommentRequest request) {
            super(request);

            fromHash = request.fromHash;
            pullRequestId = request.pullRequestId;
            repository = request.repository;
            toHash = request.toHash;
        }

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

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

            return self();
        }

        @Nonnull
        public Builder pullRequestId(@Nullable Long value) {
            pullRequestId = value;

            return self();
        }

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