/*
 * Copyright 2015-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 -- Topo View -- Topo Model Service - Unit Tests
 */
describe('factory: view/topo/topoModel.js', function() {
    var $log, fs, rnd, tms;

    // stop random numbers from being quite so random
    var mockRandom = {
        // mock spread returns s + 1
        spread: function (s) {
            return s + 1;
        },
        // mock random dimension returns d / 2 - 1
        randDim: function (d) {
            return d/2 - 1;
        },
        mock: 'yup'
    };

    // to mock out the [lng,lat] <=> [x,y] transformations, we will
    // add/subtract 2000, 3000 respectively:
    //   lng:2005 === x:5,   lat:3004 === y:4

    var mockProjection = function (lnglat) {
        return [lnglat[0] - 2000, lnglat[1] - 3000];
    };

    mockProjection.invert = function (xy) {
        return [xy[0] + 2000, xy[1] + 3000];
    };

    // our test devices and hosts:
    var dev1 = {
            'class': 'device',
            id: 'dev1',
            x: 17,
            y: 27,
            online: true
        },
        dev2 = {
            'class': 'device',
            id: 'dev2',
            x: 18,
            y: 28,
            online: true
        },
        host1 = {
            'class': 'host',
            id: 'host1',
            x: 23,
            y: 33,
            cp: {
                device: 'dev1',
                port: 7
            },
            ingress: 'dev1/7-host1'
        },
        host2 = {
            'class': 'host',
            id: 'host2',
            x: 24,
            y: 34,
            cp: {
                device: 'dev0',
                port: 0
            },
            ingress: 'dev0/0-host2'
        };


    // our test api
    var api = {
        projection: function () { return mockProjection; },
        network: {
            nodes: [dev1, dev2, host1, host2],
            links: [],
            lookup: {dev1: dev1, dev2: dev2, host1: host1, host2: host2},
            revLinkToKey: {}
        },
        restyleLinkElement: function () {},
        removeLinkElement: function () {}
    };

    // our test dimensions and well known locations..
    var dim = [20, 40],
        randLoc = [9, 19],          // random location using randDim(): d/2-1
        randHostLoc = [40, 50],     // host "near" random location
                                    //  given that 'nearDist' = 15
                                    //  and spread(15) = 16
                                    //  9 + 15 + 16 = 40; 19 + 15 + 16 = 50
        nearDev1 = [48,58],         // [17+15+16, 27+15+16]
        dev1Loc = [17,27],
        dev2Loc = [18,28],
        host1Loc = [23,33],
        host2Loc = [24,34];

    // implement some custom matchers...
    beforeEach(function () {
        jasmine.addMatchers({
            toBePositionedAt: function () {
                return {
                    compare: function (actual, xy) {
                        var result = {},
                            actCoord = [actual.x, actual.y];

                        result.pass = (actual.x === xy[0]) && (actual.y === xy[1]);

                        if (result.pass) {
                            // for negation with ".not"
                            result.message = 'Expected [' + actCoord +
                            '] NOT to be positioned at [' + xy + ']';
                        } else {
                            result.message = 'Expected [' + actCoord +
                            '] to be positioned at [' + xy + ']';
                        }
                        return result;
                    }
                }
            },
            toHaveEndPoints: function () {
                return {
                    compare: function (actual, xy1, xy2) {
                        var result = {};

                        result.pass = (actual.source.x === xy1[0]) &&
                                      (actual.source.y === xy1[1]) &&
                                      (actual.target.x === xy2[0]) &&
                                      (actual.target.y === xy2[1]);

                        if (result.pass) {
                            // for negation with ".not"
                            result.message = 'Expected ' + actual +
                            ' NOT to have endpoints [' + xy1 + ']-[' + xy2 + ']';
                        } else {
                            result.message = 'Expected ' + actual +
                            ' to have endpoints [' + xy1 + ']-[' + xy2 + ']';
                        }
                        return result;
                    }
                }
            },
            toBeFixed: function () {
                return {
                    compare: function (actual) {
                        var result = {
                            pass: actual.fixed
                        };
                        if (result.pass) {
                            result.message = 'Expected ' + actual +
                            ' NOT to be fixed!';
                        } else {
                            result.message = 'Expected ' + actual +
                            ' to be fixed!';
                        }
                        return result;
                    }
                }
            }
        });
    });

    beforeEach(module('ovTopo', 'onosUtil', 'onosNav', 'onosLayer', 'onosWidget', 'onosMast'));

    beforeEach(function () {
        module(function ($provide) {
            $provide.value('RandomService', mockRandom);
        });
    });

    beforeEach(inject(function (_$log_, FnService, RandomService, TopoModelService) {
        $log = _$log_;
        fs = FnService;
        rnd = RandomService;
        tms = TopoModelService;
        tms.initModel(api, dim);
    }));


    it('should install the mock random service', function () {
        expect(rnd.mock).toBe('yup');
        expect(rnd.spread(4)).toBe(5);
        expect(rnd.randDim(8)).toBe(3);
    });

    it('should install the mock projection', function () {
        expect(tms.coordFromLngLat({lng: 2005, lat: 3004})).toEqual([5,4]);
        expect(tms.lngLatFromCoord([5,4])).toEqual([2005,3004]);
    });

    it('should define TopoModelService', function () {
        expect(tms).toBeDefined();
    });

    it('should define api functions', function () {
        expect(fs.areFunctions(tms, [
            'initModel', 'newDim', 'destroyModel',
            'positionNode', 'resetAllLocations', 'createDeviceNode', 'createHostNode',
            'createHostLink', 'createLink',
            'coordFromLngLat', 'lngLatFromCoord',
            'findLink', 'findLinkById', 'findDevices',
            'findAttachedHosts', 'findAttachedLinks', 'findBadLinks'
        ])).toBeTruthy();
    });

    // === unit tests for positionNode()

    it('should position a node using meta x/y', function () {
        var node = {
            metaUi: { x:37, y:48 }
        };
        tms.positionNode(node);
        expect(node).toBePositionedAt([37,48]);
        expect(node).toBeFixed();
    });

    it('should position a node by translating lng/lat', function () {
        var node = {
            location: {
                type: 'lnglat',
                lng: 2008,
                lat: 3009
            }
        };
        tms.positionNode(node);
        expect(node).toBePositionedAt([8,9]);
        expect(node).toBeFixed();
    });

    it('should position a device with no location randomly', function () {
        var node = { 'class': 'device' };
        tms.positionNode(node);
        expect(node).toBePositionedAt(randLoc);
        expect(node).not.toBeFixed();
    });

    it('should position a device randomly even if x/y set', function () {
        var node = { 'class': 'device', x: 1, y: 2 };
        tms.positionNode(node);
        expect(node).toBePositionedAt(randLoc);
        expect(node).not.toBeFixed();
    });

    it('should NOT reposition a device randomly on update', function () {
        var node = { 'class': 'device', x: 1, y: 2 };
        tms.positionNode(node, true);
        expect(node).toBePositionedAt([1,2]);
        expect(node).not.toBeFixed();
    });

    it('should position a host close to its device', function () {
        var node = { 'class': 'host', cp: { device: 'dev1' } };
        tms.positionNode(node);

        // note: nearDist is 15; spread(15) adds 16; dev1 at [17,27]

        expect(node).toBePositionedAt(nearDev1);
        expect(node).not.toBeFixed();
    });

    it('should randomize host with no assoc device', function () {
        var node = { 'class': 'host', cp: { device: 'dev0' } };
        tms.positionNode(node);

        // note: no device gives 'rand loc' [9,19]
        //       nearDist is 15; spread(15) adds 16

        expect(node).toBePositionedAt(randHostLoc);
        expect(node).not.toBeFixed();
    });

    // === unit tests for createDeviceNode()

    it('should create a basic device node', function () {
        var node = tms.createDeviceNode({ id: 'foo' });
        expect(node).toBePositionedAt(randLoc);
        expect(node).not.toBeFixed();
        expect(node.class).toEqual('device');
        expect(node.svgClass).toEqual('node device');
        expect(node.id).toEqual('foo');
    });

    it('should create device node with type', function () {
        var node = tms.createDeviceNode({ id: 'foo', type: 'cool' });
        expect(node).toBePositionedAt(randLoc);
        expect(node).not.toBeFixed();
        expect(node.class).toEqual('device');
        expect(node.svgClass).toEqual('node device cool');
        expect(node.id).toEqual('foo');
    });

    it('should create online device node with type', function () {
        var node = tms.createDeviceNode({ id: 'foo', type: 'cool', online: true });
        expect(node).toBePositionedAt(randLoc);
        expect(node).not.toBeFixed();
        expect(node.class).toEqual('device');
        expect(node.svgClass).toEqual('node device cool online');
        expect(node.id).toEqual('foo');
    });

    it('should create online device node with type and lng/lat', function () {
        var node = tms.createDeviceNode({
            id: 'foo',
            type: 'yowser',
            online: true,
            location: {
                type: 'lnglat',
                lng: 2048,
                lat: 3096
            }
        });
        expect(node).toBePositionedAt([48,96]);
        expect(node).toBeFixed();
        expect(node.class).toEqual('device');
        expect(node.svgClass).toEqual('node device yowser online');
        expect(node.id).toEqual('foo');
    });

    // === unit tests for createHostNode()

    it('should create a basic host node', function () {
        var node = tms.createHostNode({ id: 'bar', cp: { device: 'dev0' } });
        expect(node).toBePositionedAt(randHostLoc);
        expect(node).not.toBeFixed();
        expect(node.class).toEqual('host');
        expect(node.svgClass).toEqual('node host endstation');
        expect(node.id).toEqual('bar');
    });

    it('should create a host with type', function () {
        var node = tms.createHostNode({
            id: 'bar',
            type: 'classic',
            cp: { device: 'dev1' }
        });
        expect(node).toBePositionedAt(nearDev1);
        expect(node).not.toBeFixed();
        expect(node.class).toEqual('host');
        expect(node.svgClass).toEqual('node host classic');
        expect(node.id).toEqual('bar');
    });

    // === unit tests for createHostLink()

    it('should create a basic host link', function () {
        var link = tms.createHostLink(host1);
        expect(link.source).toEqual(host1);
        expect(link.target).toEqual(dev1);
        expect(link).toHaveEndPoints(host1Loc, dev1Loc);
        expect(link.key).toEqual('dev1/7-host1');
        expect(link.class).toEqual('link');
        expect(link.type()).toEqual('hostLink');
        expect(link.linkWidth()).toEqual(1);
        expect(link.online()).toEqual(true);
    });

    it('should return null for failed endpoint lookup', function () {
        spyOn($log, 'error');
        var link = tms.createHostLink(host2);
        expect(link).toBeNull();
        expect($log.error).toHaveBeenCalledWith(
            'Node(s) not on map for link:\n[dst] "dev0" missing'
        );
    });

    // === unit tests for createLink()

    it('should return null for missing endpoints', function () {
        spyOn($log, 'error');
        var link = tms.createLink({src: 'dev0', dst: 'dev00'});
        expect(link).toBeNull();
        expect($log.error).toHaveBeenCalledWith(
            'Node(s) not on map for link:\n[src] "dev0" missing\n[dst] "dev00" missing'
        );
    });

    xit('should create a basic link', function () {
        var linkData = {
                src: 'dev1',
                dst: 'dev2',
                id: 'baz',
                type: 'zoo',
                online: true,
                linkWidth: 1.5
            },
            link = tms.createLink(linkData);
        expect(link.source).toEqual(dev1);
        expect(link.target).toEqual(dev2);
        expect(link).toHaveEndPoints(dev1Loc, dev2Loc);
        expect(link.key).toEqual('baz');
        expect(link.class).toEqual('link');
        expect(link.fromSource).toBe(linkData);
        expect(link.type()).toEqual('zoo');
        expect(link.online()).toEqual(true); // this is the condition failing
        expect(link.linkWidth()).toEqual(1.5);
    });

    // TODO: more unit tests for additional functions....
});
