define([
    'jquery',
    'bitbucket/util/events',
    'bitbucket/internal/feature/tasks/model/task',
    'bitbucket/internal/feature/tasks/model/task-state'
], function (
    $,
    events,
    TaskModel,
    TaskState
) {

    'use strict';

    module('tasks-model', {
        setup: function () {
            var self = this;
            this.task = new TaskModel({
                anchor: {
                    id: 1,
                    type: TaskModel.Anchor.COMMENT
                },
                text: 'Dummy text'
            });
            this.eventSpy = sinon.spy(events, 'trigger');
            this.syncFunc = $.noop;
            this.syncMock = sinon.stub(this.task, 'sync', () => {
                var deferred = $.Deferred();
                this.syncFunc(deferred);
                return deferred.promise();
            });

        },
        teardown: function () {
            this.eventSpy.restore();
            this.syncMock.restore();
        }
    });

    test('fires correct events for a same resolved state save', function () {
        this.syncFunc = function (deferred) {
            deferred.resolve(); // same state
        };

        this.task.transitionToNextState();
        ok(this.eventSpy.calledWith('bitbucket.internal.feature.pull-request-tasks.resolved'));
        equal(this.eventSpy.callCount, 1);

        equal(this.task.getState(), TaskState.RESOLVED);
    });

    test('fires correct events for a same state reopen save', function () {
        this.task.set({ state: TaskState.RESOLVED, id: 999 });

        this.syncFunc = function (deferred) {
            deferred.resolve(); // same state
        };

        this.task.transitionToNextState();

        ok(this.eventSpy.calledWith('bitbucket.internal.feature.pull-request-tasks.reopened'));
        equal(this.eventSpy.callCount, 1);

        equal(this.task.getState(), TaskState.OPEN);
    });

    test('fires correct events for a diff state save', function () {
        this.syncFunc = function (deferred) {
            this.task.setState(TaskState.OPEN);
            deferred.resolve();
        };

        this.task.transitionToNextState();
        ok(this.eventSpy.calledWith('bitbucket.internal.feature.pull-request-tasks.created'));
        ok(this.eventSpy.calledWith('bitbucket.internal.feature.pull-request-tasks.resolved'));
        equal(this.eventSpy.callCount, 2);

        equal(this.task.getState(), TaskState.OPEN);
    });

    test('fires correct events for a failed save', function () {
        this.syncFunc = function (deferred) {
            deferred.reject();
        };

        this.task.transitionToNextState();

        ok(this.eventSpy.calledWith('bitbucket.internal.feature.pull-request-tasks.resolved'), "Resolved event should be triggered");
        ok(this.eventSpy.calledWith('bitbucket.internal.feature.pull-request-tasks.failed-transition'), "Failed Transition event should be triggered");
        equal(this.eventSpy.callCount, 2);

        equal(this.task.getState(), TaskState.OPEN);
    });

    test('sanitises text strings', function () {
        equal(TaskModel.sanitiseText(""), "");
        equal(TaskModel.sanitiseText("Hi Mum!"), "Hi Mum!");
        equal(TaskModel.sanitiseText("        foo bar      "), "foo bar");
        equal(TaskModel.sanitiseText("\n\n\n\nWord\n\n       up.\t\tDoge.\n\n\n:)"), "Word up. Doge. :)");
        equal(TaskModel.sanitiseText("One\nTwo\nThree  "), "One Two Three");
    });

});

