/* global AJS:false */
AJS.test.require("com.atlassian.bitbucket.server.bitbucket-branch:automerge-decorator-resources", function() {

    var $ = require('jquery');
    var automerge = require('branch/automerge-decorator');
    var navbuilder = require('bitbucket/util/navbuilder');
    var RevisionReference = require('bitbucket/internal/model/revision-reference');

    function getMergeDiagram() {
        $('<div class="aui-layer"></div>').appendTo('#qunit-fixture');
        return $('<div class="branch-diagram branch-diagram-merge"></div>').appendTo('.aui-layer');
    }

    function mockRef(displayId) {
        return new RevisionReference({
            'id' : 'refs/heads/' + displayId,
            'displayId' : displayId,
            'type' : RevisionReference.type.BRANCH,
            'repository' : {
                slug : 'REPO',
                project : { key : 'PROJ' }
            }
        });
    }

    function mockPullRequest() {
        var toRef = mockRef('release/1.0');
        var fromRef = mockRef('feature/FEAT-1-test-feature');

        return {
            getToRef : function() { return toRef; },
            getFromRef : function()  { return fromRef; }
        };
    }

    function mockMergePath(mergePathLength) {
        var mergePath = [];

        for (var i = 0; i < mergePathLength; i++) {
            mergePath.push(mockRef('release/1.' + i));
        }

        mergePath.push(mockRef('master'));

        return mergePath;
    }


    module('automerge-decorator', {
        setup: function () {
            this.server = sinon.fakeServer.create();
        },
        teardown: function () {
            this.server.restore();
        }
    });


    function mockServerResponse(server, autoMergeEnabled, toRef, mergePathLength) {
        function getJsonResponse() {
            var jsonResponse;
            if (autoMergeEnabled) {
                jsonResponse = JSON.stringify({
                    "status": {
                        "id": 'PROCEED',
                        "available": true
                    },
                    "path" : mockMergePath(mergePathLength)
                });
            } else {
                if (mergePathLength > 30 ) {
                    jsonResponse = JSON.stringify({
                        "status": {
                            "id": 'PATH_TOO_LONG',
                            "available": false
                        }
                    });
                } else {
                    jsonResponse = JSON.stringify({
                        "status": {
                            "id": 'NO_PATH',
                            "available": false
                        }
                    });
                }
            }
            return jsonResponse;
        }

        server.respondWith("GET",
            navbuilder.rest('branch-utils')
                .project('PROJ')
                .repo('REPO')
                .addPathComponents('automerge', 'path')
                .withParams({branchRefId: toRef})
                .build(),
            [200, { "Content-Type": "application/json" }, getJsonResponse()]
        );
    }

    test('Test Automerge with 1 downstream branch', function() {

        mockServerResponse(this.server, true, 'refs/heads/release/1.0', 1);
        automerge.decorateDiagram(getMergeDiagram(), mockPullRequest());
        this.server.respond();

        ok($('.branch-diagram').hasClass('branch-diagram-automerge'), 'Merge Branch Diagram is replaced with Automerge Diagram');
        strictEqual($('.automerge-path').find('.ref-lozenge').length, 1, 'Found 1 branch for downstream automerge');
        strictEqual($('.automerge-path').find('.ref-lozenge .name').text(), 'master', 'Automerge branch name is \'master\'');
        ok(!$('expand-automerge-path-button').length, 'Show more branches link NOT shown');

    });

    test('Test Automerge with 2 downstream branches', function() {

        mockServerResponse(this.server, true, 'refs/heads/release/1.0', 2);
        automerge.decorateDiagram(getMergeDiagram(), mockPullRequest());
        this.server.respond();

        ok($('.branch-diagram').hasClass('branch-diagram-automerge'), 'Merge Branch Diagram is replaced with Automerge Diagram');
        strictEqual($('.automerge-path').find('.ref-lozenge').length, 2, 'Found 2 branches for downstream automerge');
        ok(!$('expand-automerge-path-button').length, 'Show more branches link NOT shown');

    });

    test('Test Automerge with 3 downstream branches', function() {

        mockServerResponse(this.server, true, 'refs/heads/release/1.0', 3);
        automerge.decorateDiagram(getMergeDiagram(), mockPullRequest());
        this.server.respond();

        ok($('.branch-diagram').hasClass('branch-diagram-automerge'), 'Merge Branch Diagram is replaced with Automerge Diagram');
        strictEqual($('.automerge-path').find('.ref-lozenge').length, 3, 'Found 3 branches for downstream automerge');
        ok($('#expand-automerge-path-button').length, 'Show more branches link is shown');
        strictEqual($('#expand-automerge-path-button').text(), 'and 2 more branches', 'Show more branches text says 2 branches are hidden');

        ok($('.automerge-path').hasClass('collapsed'), 'automerge path ref lozenges are collapsed');
        $('#expand-automerge-path-button').trigger('click');
        ok(!$('.automerge-path').hasClass('collapsed'), 'collapsed automerge path ref lozenges are shown');
    });

    test('Test Automerge with 10 downstream branches', function() {

        mockServerResponse(this.server, true, 'refs/heads/release/1.0', 10);
        automerge.decorateDiagram(getMergeDiagram(), mockPullRequest());
        this.server.respond();

        ok($('.branch-diagram').hasClass('branch-diagram-automerge'), 'Merge Branch Diagram is replaced with Automerge Diagram');
        strictEqual($('.automerge-path').find('.ref-lozenge').length, 10, 'Found 10 branches for downstream automerge');
        strictEqual($('#expand-automerge-path-button').text(), 'and 9 more branches', 'Show more branches text says 9 branches are hidden');

        ok($('.automerge-path').hasClass('collapsed'), 'automerge path ref lozenges are collapsed');
        $('#expand-automerge-path-button').trigger('click');
        ok(!$('.automerge-path').hasClass('collapsed'), 'collapsed automerge path ref lozenges are shown');

    });

    test('Test pull request with no automerge', function() {

        mockServerResponse(this.server, false, 'refs/heads/release/1.0');
        automerge.decorateDiagram(getMergeDiagram(), mockPullRequest());
        this.server.respond();

        ok($('.branch-diagram').hasClass('branch-diagram-merge'), 'Merge Branch Diagram is retained');
        ok(!$('.automerge-path').length, 'Automerge path ref lozenges are not shown');
    });

    test('Test pull request with more than 100 downstream branches', function() {

        mockServerResponse(this.server, false, 'refs/heads/release/1.0', 35);
        automerge.decorateDiagram(getMergeDiagram(), mockPullRequest());
        this.server.respond();

        ok($('.branch-diagram').hasClass('branch-diagram-merge'), 'Merge Branch Diagram is retained');
        ok(!$('.automerge-path').length, 'Automerge path ref lozenges are not shown');
        ok($('.branch-diagram').next('.aui-message').hasClass('aui-message-warning'), 'Warning about automerge not being triggered is shown');
    });

});