package com.atlassian.bitbucket.content;

import com.atlassian.bitbucket.pull.PullRequestMergeRequest;
import com.atlassian.bitbucket.pull.PullRequestService;

import javax.annotation.Nonnull;

/**
 * Describes two {@link ConflictChange conflicting changes} that were made on opposite sides of a merge.
 * <p>
 * When performing a merge, there an implicit third revision is used to produce a three-way merge. This third revision
 * is the most recent shared ancestor between the two branches being merged. In the revisions on the incoming branch
 * ("their" side) and destination branch ("our" side) after the common ancestor it is possible that the same files have
 * been modified in different ways. When this happens, the resulting conflict consists of the {@link ConflictChange
 * change} made on the destination branch ({@link #getOurChange() "our" change}) and the change made on the incoming
 * branch ({@link #getTheirChange()} "their" change).
 * <p>
 * Because the {@link ConflictChange conflicting changes} only describe the changed paths and the {@link ChangeType
 * type of change}, it is possible for both changes to be the same. Such a case indicates that the same type of change
 * was made differently to the same files. For example, the same file may be {@link ChangeType#MODIFY modified} in
 * different ways on both branches.
 *
 * @see PullRequestService#merge(PullRequestMergeRequest)
 */
public interface Conflict {

    /**
     * Retrieves "our" change, which describes the change that was made on the destination branch relative to a shared
     * ancestor with the incoming branch.
     *
     * @return the destination branch's change
     */
    @Nonnull
    ConflictChange getOurChange();

    /**
     * Retrieves "their" change, which describes the change that was made on the incoming branch relative to a shared
     * ancestor with the destination branch.
     *
     * @return the incoming branch's change
     */
    @Nonnull
    ConflictChange getTheirChange();
}
