/*
 * Copyright 2014-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 ONOS GUI -- Key Handler Service - Unit Tests
 */
xdescribe('factory: fw/util/keys.js', function() {
    var $log, ks, fs, qhs,
        d3Elem, elem, last;
  

    beforeEach(module('onosUtil', 'onosSvg', 'onosLayer', 'onosNav', 'onosRemote'));

    beforeEach(inject(function (_$log_, KeyService, FnService, QuickHelpService) {
        $log = _$log_;
        ks = KeyService;
        fs = FnService;
        qhs = QuickHelpService;
        d3Elem = d3.select('body').append('p').attr('id', 'ptest');
        elem = d3Elem.node();
        ks.installOn(d3Elem);
        ks.bindQhs(qhs);
        last = {
            view: null,
            key: null,
            code: null,
            ev: null
        };
    }));

    afterEach(function () {
        d3.select('#ptest').remove();
    });

    it('should define the key service', function () {
        expect(ks).toBeDefined();
    });

    it('should define api functions', function () {
        expect(fs.areFunctions(ks, [
            'bindQhs', 'installOn', 'keyBindings', 'gestureNotes', 'enableKeys'
        ])).toBeTruthy();
    });

    // This no longer works because 'initKeyboardEvent' has been depreciated.
    // Now there is a constructor for 'KeyboardEvent' where you can modify
    //      the new event with a dictionary(?) 'KeyboardEventInit'.
    // However, the below code has been so recently depreciated, there are no
    //      examples online of how to use the new interface, and some browsers
    //      don't support it still. These tests will have to be put off for a
    //      while more. (Investigated 4/28/15)
    // Also tried was Angular's triggerHandler() function, but it doesn't seem
    //      that it can take arguments about the event.
    // Using jQuery in tests might be a good idea, for triggering test events.
    function jsKeyDown(element, code) {
        var ev = document.createEvent('KeyboardEvent');

        // Chromium Hack
        if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
            Object.defineProperty(ev, 'keyCode', {
                get: function () { return this.keyCodeVal; }
            });
            Object.defineProperty(ev, 'which', {
                get: function () { return this.keyCodeVal; }
            });
        }

        if (ev.initKeyboardEvent) {
            ev.initKeyboardEvent('keydown', true, true, document.defaultView,
                                false, false, false, false, code, code);
        } else {
            ev.initKeyEvent('keydown', true, true, document.defaultView,
                            false, false, false, false, code, 0);
        }

        ev.keyCodeVal = code;

        if (ev.keyCode !== code) {
            console.warn("keyCode mismatch " + ev.keyCode +
                        "(" + ev.which + ") -> "+ code);
        }
        element.dispatchEvent(ev);
    }

    // === Key binding related tests
    it('should start with default key bindings', function () {
        var state = ks.keyBindings(),
            gk = state.globalKeys,
            mk = state.maskedKeys,
            vk = state.viewKeys,
            vf = state.viewFunction;

        expect(gk.length).toEqual(4);
        ['backSlash', 'slash', 'esc', 'T'].forEach(function (k) {
            expect(fs.contains(gk, k)).toBeTruthy();
        });

        expect(mk.length).toEqual(3);
        ['backSlash', 'slash', 'T'].forEach(function (k) {
            expect(fs.contains(mk, k)).toBeTruthy();
        });

        expect(vk.length).toEqual(0);
        expect(vf).toBeFalsy();
    });

    function bindTestKeys(withDescs) {
        var keys = ['A', '1', 'F5', 'equals'],
            kb = {};

        function cb(view, key, code, ev) {
            last.view = view;
            last.key = key;
            last.code = code;
            last.ev = ev;
        }

        function bind(k) {
            return withDescs ? [cb, 'desc for key ' + k] : cb;
        }

        keys.forEach(function (k) {
            kb[k] = bind(k);
        });

        ks.keyBindings(kb);
    }

    function verifyCall(key, code) {
        // TODO: update expectation, when view tokens are implemented
        expect(last.view).toEqual('NotYetAViewToken');
        last.view = null;

        expect(last.key).toEqual(key);
        last.key = null;

        expect(last.code).toEqual(code);
        last.code = null;

        expect(last.ev).toBeTruthy();
        last.ev = null;
    }

    function verifyNoCall() {
        expect(last.view).toBeNull();
        expect(last.key).toBeNull();
        expect(last.code).toBeNull();
        expect(last.ev).toBeNull();
    }

    function verifyTestKeys() {
        jsKeyDown(elem, 65); // 'A'
        verifyCall('A', 65);
        jsKeyDown(elem, 66); // 'B'
        verifyNoCall();

        jsKeyDown(elem, 49); // '1'
        verifyCall('1', 49);
        jsKeyDown(elem, 50); // '2'
        verifyNoCall();

        jsKeyDown(elem, 116); // 'F5'
        verifyCall('F5', 116);
        jsKeyDown(elem, 117); // 'F6'
        verifyNoCall();

        jsKeyDown(elem, 187); // 'equals'
        verifyCall('equals', 187);
        jsKeyDown(elem, 189); // 'dash'
        verifyNoCall();

        var vk = ks.keyBindings().viewKeys;

        expect(vk.length).toEqual(4);
        ['A', '1', 'F5', 'equals'].forEach(function (k) {
            expect(fs.contains(vk, k)).toBeTruthy();
        });

        expect(ks.keyBindings().viewFunction).toBeFalsy();
    }

    // TODO: jsKeyDown(...) no longer emulates key presses ?! :(
    // The following four unit tests ignored until we can figure this out.
    // INVESTIGATED: see jsKeyDown for details...

    xit('should allow specific key bindings', function () {
        bindTestKeys();
        verifyTestKeys();
    });

    xit('should allow specific key bindings with descriptions', function () {
        bindTestKeys(true);
        verifyTestKeys();
    });

    xit('should warn about masked keys', function () {
        var k = {'space': cb, 'T': cb},
            count = 0;

        function cb(token, key, code, ev) {
            count++;
            //console.debug('count = ' + count, token, key, code);
        }

        spyOn($log, 'warn');

        ks.keyBindings(k);

        expect($log.warn).toHaveBeenCalledWith('setKeyBindings(): Key "T" is reserved');

        // the 'T' key should NOT invoke our callback
        expect(count).toEqual(0);
        jsKeyDown(elem, 84); // 'T'
        expect(count).toEqual(0);

        // but the 'space' key SHOULD invoke our callback
        jsKeyDown(elem, 32); // 'space'
        expect(count).toEqual(1);
    });

    xit('should block keys when disabled', function () {
        var cbCount = 0;

        function cb() { cbCount++; }

        function pressA() { jsKeyDown(elem, 65); }  // 65 == 'A' keycode

        ks.keyBindings({ A: cb });

        expect(cbCount).toBe(0);

        pressA();
        expect(cbCount).toBe(1);

        ks.enableKeys(false);
        pressA();
        expect(cbCount).toBe(1);

        ks.enableKeys(true);
        pressA();
        expect(cbCount).toBe(2);
    });

    // === Gesture notes related tests
    it('should start with no notes', function () {
        expect(ks.gestureNotes()).toEqual([]);
    });

    it('should allow us to add nodes', function () {
        var notes = [
            ['one', 'something about one'],
            ['two', 'description of two']
        ];
        ks.gestureNotes(notes);

        expect(ks.gestureNotes()).toEqual(notes);
    });

    it('should ignore non-arrays', function () {
        ks.gestureNotes({foo:4});
        expect(ks.gestureNotes()).toEqual([]);
    });

    // Consider adding test to ensure array contains 2-tuples of strings
});
