package com.atlassian.bitbucket.content;

import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestDiffRequest;
import com.atlassian.bitbucket.pull.PullRequestService;

/**
 * Used to mark {@link DiffLine diff lines} which represent a merge conflict. Lines which are streamed via a
 * {@link DiffContentCallback#onSegmentLine(String, ConflictMarker, boolean) callback} will be similarly marked.
 * <p>
 * Conflicts are a natural possibility when {@link PullRequestService#merge(int, long, int)
 * merging} {@link PullRequest pull requests}. They are not expected to appear in normal
 * commit diffs, as it is assumed conflicts were resolved before the changes were committed to the repository. The
 * system will <i>never</i> introduce merge commits which include conflicts into a repository when merging a pull
 * request; the merge attempt will throw an exception instead. Such conflicts will only be shown when
 * {@link PullRequestService#streamDiff(PullRequestDiffRequest,
 * DiffContentCallback)} streaming the diff} for a pull request.
 */
public enum ConflictMarker {

    /**
     * Indicates the line is a conflict marker.
     * <p>
     * Conflict markers come in three types:
     * <ul>
     *     <li>&lt;&lt;&lt;&lt;&lt;&lt;&lt;: Signals the beginning of {@link #OURS our} lines</li>
     *     <li>=======: Signals the end of {@link #OURS our} lines and the beginning of {@link #THEIRS theirs}</li>
     *     <li>&gt;&gt;&gt;&gt;&gt;&gt;&gt;: Signals the end of {@link #THEIRS their} lines</li>
     * </ul>
     * The markers will always appear in the diff in the above order, and if any marker is seen all three will always
     * be seen (unless the {@link DiffSegment segment} is {@link DiffSegment#isTruncated() truncated}).
     */
    MARKER,
    /**
     * Indicates the line comes from our version of the file. This is the version that is already on the branch to
     * which the changes are being merged.
     * <p>
     * Note: Our lines always appear as {@link DiffSegmentType#CONTEXT context} lines, because they are in the file
     * already. As they are context, how many appear in the diff is dependent on the amount of context being shown.
     * That means it is possible that some number of our lines will be omitted, if the markers bound a set of lines
     * greater than the amount of context being shown. If any lines are omitted, it will cause our lines to be split
     * into two separate {@link DiffHunk hunks} (and, implicitly, into two {@link DiffSegment segments} as well).
     */
    OURS,
    /**
     * Indicates the line comes from their version of the file. This is the version that is being merged into the
     * branch.
     * <p>
     * Note: Their lines always appear as {@link DiffSegmentType#ADDED added} lines. Because they will never be
     * {@link DiffSegmentType#CONTEXT context} lines, they will all always appear in the diff, in a single segment
     * (unless the {@link DiffSegment segment} is {@link DiffSegment#isTruncated() truncated}).
     */
    THEIRS,
}
