/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 [longOrX,latOrY] <=> [x,y] transformations, we will
    // add/subtract 2000, 3000 respectively:
    //   longOrX:2005 === x:5,   latOrY: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({longOrX: 2005, latOrY: 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', 'findHosts',
            '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: {
                locType: 'geo',
                longOrX: 2008,
                latOrY: 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: {
                locType: 'geo',
                longOrX: 2048,
                latOrY: 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()

    // TODO: fix this test to use new createHostLink(...) API
    xit('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);
    });

    // TODO: fix this test to use new createHostLink(...) API
    xit('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....
});
