/* global AJS:false */
AJS.test.require("com.atlassian.bitbucket.server.bitbucket-web:pull-request-edit", function() {
    'use strict';

    var PullRequestEdit = require('bitbucket/internal/feature/pull-request-edit');
    var _ = require('lodash');

    var basePullRequest = {
        title: 'The title',
        description: 'The description',
        reviewers : [],
        toRef: {
            id: 'refs/heads/master'
        },
        version: 1
    };

    module('pull-request-edit', {
        setup: function() {
            this.baseline = _.merge({}, basePullRequest);
            this.them = _.merge({}, basePullRequest, { version: 2 });
            this.us = _.merge({}, basePullRequest);
        }
    });

    test('Merge pull request update - no updates', function() {
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - us title', function() {
        this.us.title = 'Updated title';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(_.merge({}, this.them, { title: 'Updated title' }), result);
    });

    test('Merge pull request update - them title', function() {
        this.them.title = 'Updated title';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - both title', function() {
        this.us.title = 'Updated title';
        this.them.title = 'Updated title';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - conflict title', function() {
        this.us.title = 'Updated title';
        this.them.title = 'Updated previously title';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        equal(null, result);
    });

    test('Merge pull request update - us description', function() {
        this.us.description = 'Updated description';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(_.merge({}, this.them, { description: 'Updated description' }), result);
    });

    test('Merge pull request update - them description', function() {
        this.them.description = 'Updated description';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - both description', function() {
        this.us.description = 'Updated description';
        this.them.description = 'Updated description';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - conflict description', function() {
        this.us.description = 'Updated description';
        this.them.description = 'Updated previously description';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        equal(null, result);
    });

    test('Merge pull request update - version ignored', function() {
        this.us.version = 2;
        this.them.version = 3;
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - us toRef', function() {
        this.us.toRef.id = 'refs/heads/release/3.4';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(_.merge({}, this.them, { toRef : { id: 'refs/heads/release/3.4' }}), result);
    });

    test('Merge pull request update - them toRef', function() {
        this.them.toRef.id = 'refs/heads/release/3.4';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - both toRef', function() {
        this.us.toRef.id = 'refs/heads/release/3.4';
        this.them.toRef.id = 'refs/heads/release/3.4';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - conflict toRef', function() {
        this.us.toRef.id = 'refs/heads/release/3.4';
        this.them.toRef.id = 'refs/heads/release/3.5';
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        equal(null, result);
    });

    test('Merge pull request update - us reviewers', function() {
        var delta = { reviewers : [{ user : { name : 'batman' } }] };
        _.merge(this.us, delta);
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(_.merge({}, this.them, delta), result);
    });

    test('Merge pull request update - them reviewers', function() {
        var delta = { reviewers : [{ user : { name : 'batman' } }] };
        _.merge(this.them, delta);
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - both reviewers', function() {
        var delta = { reviewers : [{ user : { name : 'batman' } }] };
        _.merge(this.us, delta);
        _.merge(this.them, delta);
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        deepEqual(this.them, result);
    });

    test('Merge pull request update - conflict reviewers', function() {
        // At some point in the future, we may want this to succeed, but for now it fails
        _.merge(this.us, { reviewers : [{ user : { name : 'batman' } }] });
        _.merge(this.them, { reviewers : [{ user : { name : 'robin' } }] });
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, this.baseline, this.them, this.us);
        equal(null, result);
    });

    test('Merge pull request update - additional fields ignored', function() {
        var taintedBaseline = _.merge({}, this.baseline, { blah: 'blah1', toRef: { isDefault: NaN } });
        var taintedUs = _.merge({}, this.us, { blah: 'blah2', toRef: { isDefault: false }  });
        var taintedThem = _.merge({}, this.them, { blah: 'blah3', toRef: { isDefault: true }  });
        var result = PullRequestEdit.prototype.mergePullRequestUpdate.call(null, taintedBaseline, taintedThem, taintedUs);
        deepEqual(this.them, result);
    });

});