define([
    'bacon',
    'lodash',
    'bitbucket/internal/util/bacon',
    'bitbucket/internal/util/events'
], function(
    Bacon,
    _,
    baconUtil,
    events
) {

    'use strict';

    module('util-bacon');

    function splitArray(input) {
        return baconUtil.toArray(baconUtil.split(Bacon.fromArray(input), _.identity));
    }

    test('Split: Flushes last group onEnd', function() {
        deepEqual(splitArray([1, 1, 2, 2]), [[1, 1], [2, 2]]);
    });

    test('Split: Not grouping by all values', function() {
        deepEqual(splitArray([1, 1, 2, 1]), [[1, 1], [2], [1]]);
    });

    test('Split: Empty stream', function() {
        deepEqual(splitArray([]), []);
    });

    function betweenArray(input, start, end, startInclusive, endInclusive, equals) {
        return baconUtil.toArray(baconUtil.takeBetween(Bacon.fromArray(input), {
            start : start,
            end : end,
            startInclusive : startInclusive,
            endInclusive : endInclusive,
            equals : equals
        }));
    }

    test('takeBetween: empty', function() {
        deepEqual(betweenArray([], 2, 4, true, true), []);
    });

    test('takeBetween: none inclusive', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 2, 4, false, false), [3]);
    });

    test('takeBetween: start inclusive', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 2, 4, true, false), [2, 3]);
    });

    test('takeBetween: start inclusive', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 2, 4, false, true), [3, 4]);
    });

    test('takeBetween: both inclusive', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 2, 4, true, true), [2, 3, 4]);
    });

    test('takeBetween: reversed', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 4, 2, true, false), [3, 4]);
    });

    test('takeBetween: same element inclusive', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 2, 2, true, true), [ 2 ]);
    });

    test('takeBetween: same element exclusive', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 2, 2, false, false), []);
    });

    test('takeBetween: same element not found', function() {
        deepEqual(betweenArray([1, 2, 3, 4, 5], 6, 6, true, true), []);
    });

    test('takeBetween: custom equality', function() {
        deepEqual(betweenArray([[1], [2], [3], [4], [5]], [2], [4], true, true, function(a, b) {
            return a[0] === b[0];
        }), [[2], [3], [4]]);
    });

    test('Events', function() {
        var results = [];
        // Be nice to use toArray() but it's a chicken and egg problem with listening for the events
        var unsub = baconUtil.events('a.b.c').onValue(function(result) {
            results.push(result);
        });
        events.trigger('a.b.c', null, 'x');
        events.trigger('a.b.c', null, 'y');
        unsub();
        events.trigger('a.b.c', null, 'z');
        deepEqual(results, ['x', 'y']);
    });
});
