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

import com.atlassian.bitbucket.commit.NoSuchCommitException;
import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.i18n.KeyedMessage;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestRef;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.stash.internal.scm.git.command.merge.AbstractMergeBaseExitHandler;

import javax.annotation.Nonnull;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Handles the situation where there is no common ancestor between the {@link PullRequest#getFromRef() from} and
 * {@link PullRequest#getToRef() to} refs on a {@link PullRequest pull request}.
 *
 * @since 2.9
 */
public class PullRequestMergeBaseExitHandler extends AbstractMergeBaseExitHandler {

    public static final Pattern PATTERN_COMMIT_NOT_FOUND =
            Pattern.compile("fatal: Not a valid commit name (?:([^:]*):?(.*))");

    private final PullRequest pullRequest;

    public PullRequestMergeBaseExitHandler(@Nonnull I18nService i18nService, @Nonnull PullRequest pullRequest) {
        super(i18nService, pullRequest.getToRef().getRepository());

        this.pullRequest = pullRequest;
    }

    @Override
    protected void evaluateStdErr(String stdErr, String command) {
        Matcher matcher = PATTERN_COMMIT_NOT_FOUND.matcher(stdErr);

        if (matcher.matches()) {
            String commitId = matcher.group(1);
            String branchName = pullRequest.getToRef().getLatestCommit().equals(commitId) ?
                    pullRequest.getToRef().getDisplayId() : pullRequest.getFromRef().getDisplayId();
            throw new NoSuchCommitException(i18nService.createKeyedMessage("bitbucket.git.pullrequest.merge.nocommit",
                    branchName, commitId), commitId);
        }

        super.evaluateStdErr(stdErr, command);
    }

    @Override
    protected KeyedMessage noCommonAncestorMessage() {
        PullRequestRef toRef = pullRequest.getToRef();
        Repository repository = toRef.getRepository();

        return i18nService.createKeyedMessage("bitbucket.git.pullrequest.merge.nocommonancestor",
                pullRequest.getFromRef().getDisplayId(), toRef.getDisplayId(), pullRequest.getId(),
                repository.getProject().getKey(), repository.getSlug());
    }
}
