package com.atlassian.stash.internal.pull.comment.diff;

import com.atlassian.bitbucket.content.DiffHunk;
import com.atlassian.bitbucket.content.DiffSegmentType;
import com.atlassian.stash.internal.comment.InternalComment;
import com.atlassian.stash.internal.pull.InternalPullRequest;
import com.atlassian.stash.internal.pull.InternalPullRequestCommentActivity;
import com.atlassian.stash.internal.pull.InternalPullRequestDiffCommentAnchor;
import com.atlassian.bitbucket.property.PropertyMap;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import org.junit.Test;

import static com.atlassian.bitbucket.content.DiffSegmentType.*;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;

public class DiffContextTest {

    @Test
    public void testHunksWithSpans() {
        assertHunk(createHunk(9, 10, ADDED, REMOVED, REMOVED, REMOVED), 9, 4, 10, 2);
        assertHunk(createHunk(48, 51, REMOVED, CONTEXT, ADDED, ADDED), 48, 3, 51, 4);
    }

    private static void assertHunk(DiffHunk hunk, int sourceLine, int sourceSpan, int destLine, int destSpan) {
        assertEquals("sourceLine", sourceLine, hunk.getSourceLine());
        assertEquals("sourceSpan", sourceSpan, hunk.getSourceSpan());
        assertEquals("destinationLine", destLine, hunk.getDestinationLine());
        assertEquals("destinationSpan", destSpan, hunk.getDestinationSpan());
    }

    private static Function<DiffSegmentType, DiffContextLine> createContextLine(final int start, final int end) {
        return new Function<DiffSegmentType, DiffContextLine>() {

            @Override
            public DiffContextLine apply(DiffSegmentType type) {
                return new DiffContextLine(type, start, end, "line", null, false);
            }
        };
    }

    private InternalPullRequestCommentActivity buildActivity() {
        InternalPullRequest pr = new InternalPullRequest.Builder().globalId(0L).scopedId(1L).build();

        return new InternalPullRequestCommentActivity.Builder(pr)
                .comment(new InternalComment.Builder().id(0L).build())
                .commentAnchor(new InternalPullRequestDiffCommentAnchor.Builder(pr).path("a.txt").build())
                .build();
    }

    @SuppressWarnings("ConstantConditions")
    private DiffHunk createHunk(int start, int end, DiffSegmentType... types) {
        InternalPullRequestCommentActivity activity = buildActivity();
        DiffContext context = new DiffContext(new DiffComment(activity, PropertyMap.EMPTY),
                // Technically we only care about the numbers of the first before line
                createContextLine(start, end).apply(CONTEXT), Lists.transform(asList(types), createContextLine(start, end)));
        context.done();
        // There will only ever be one
        return activity.getDiff().getHunks().get(0);
    }
}
