/*
 * Copyright 2018-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.
 */
import {async, ComponentFixture, TestBed} from '@angular/core/testing';

import {ForceSvgComponent} from './forcesvg.component';
import {
    FnService, IconService,
    LionService,
    LogService, SvgUtilService,
    UrlFnService,
    WebSocketService
} from 'org_onosproject_onos/web/gui2-fw-lib/public_api';
import {DraggableDirective} from './draggable/draggable.directive';
import {ActivatedRoute, Params} from '@angular/router';
import {of} from 'rxjs';
import {DeviceNodeSvgComponent} from './visuals/devicenodesvg/devicenodesvg.component';
import {SubRegionNodeSvgComponent} from './visuals/subregionnodesvg/subregionnodesvg.component';
import {HostNodeSvgComponent} from './visuals/hostnodesvg/hostnodesvg.component';
import {LinkSvgComponent} from './visuals/linksvg/linksvg.component';
import {Device, Host, Link, LinkType, LinkHighlight, Region} from './models';
import {ChangeDetectorRef, SimpleChange} from '@angular/core';
import {TopologyService} from '../../topology.service';
import {BadgeSvgComponent} from './visuals/badgesvg/badgesvg.component';

class MockActivatedRoute extends ActivatedRoute {
    constructor(params: Params) {
        super();
        this.queryParams = of(params);
    }
}

class MockIconService {
    loadIconDef() { }
}

class MockSvgUtilService {

    cat7() {
        const tcid = 'd3utilTestCard';

        function getColor(id, muted, theme) {
            // NOTE: since we are lazily assigning domain ids, we need to
            //       get the color from all 4 scales, to keep the domains
            //       in sync.
            const ln = '#5b99d2';
            const lm = '#9ebedf';
            const dn = '#5b99d2';
            const dm = '#9ebedf';
            if (theme === 'dark') {
                return muted ? dm : dn;
            } else {
                return muted ? lm : ln;
            }
        }

        return {
            // testCard: testCard,
            getColor: getColor,
        };
    }
}

class MockUrlFnService { }

class MockWebSocketService {
    createWebSocket() { }
    isConnected() { return false; }
    unbindHandlers() { }
    bindHandlers() { }
}

class MockTopologyService {
    public instancesIndex: Map<string, number>;
    constructor() {
        this.instancesIndex = new Map();
    }
}

describe('ForceSvgComponent', () => {
    let fs: FnService;
    let ar: MockActivatedRoute;
    let windowMock: Window;
    let logServiceSpy: jasmine.SpyObj<LogService>;
    let component: ForceSvgComponent;
    let fixture: ComponentFixture<ForceSvgComponent>;
    const openflowSampleData = require('./tests/test-module-topo2CurrentRegion.json');
    const openflowRegionData: Region = <Region><unknown>(openflowSampleData.payload);

    const odtnSampleData = require('./tests/test-OdtnConfig-topo2CurrentRegion.json');
    const odtnRegionData: Region = <Region><unknown>(odtnSampleData.payload);

    const topo2BaseData = require('./tests/topo2Highlights-base-data.json');
    const topo2BaseRegionData: Region = <Region><unknown>(topo2BaseData.payload);

    const highlightSampleData = require('./tests/topo2Highlights-sample.json');
    const linkHightlights: LinkHighlight[] = <LinkHighlight[]><unknown>(highlightSampleData.payload.links);

    const emptyRegion: Region = <Region>{devices: [ [], [], [] ], hosts: [ [], [], [] ], links: []};

    beforeEach(() => {
        const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
        ar = new MockActivatedRoute({ 'debug': 'txrx' });

        windowMock = <any>{
            location: <any>{
                hostname: 'foo',
                host: 'foo',
                port: '80',
                protocol: 'http',
                search: { debug: 'true' },
                href: 'ws://foo:123/onos/ui/websock/path',
                absUrl: 'ws://foo:123/onos/ui/websock/path'
            }
        };

        const bundleObj = {
            'core.view.Topo': {
                test: 'test1'
            }
        };
        const mockLion = (key) => {
            return bundleObj[key] || '%' + key + '%';
        };

        fs = new FnService(ar, logSpy, windowMock);

        TestBed.configureTestingModule({
            declarations: [
                ForceSvgComponent,
                DeviceNodeSvgComponent,
                HostNodeSvgComponent,
                SubRegionNodeSvgComponent,
                LinkSvgComponent,
                DraggableDirective,
                BadgeSvgComponent
            ],
            providers: [
                { provide: LogService, useValue: logSpy },
                { provide: ActivatedRoute, useValue: ar },
                { provide: FnService, useValue: fs },
                { provide: ChangeDetectorRef, useClass: ChangeDetectorRef },
                { provide: UrlFnService, useClass: MockUrlFnService },
                { provide: WebSocketService, useClass: MockWebSocketService },
                { provide: LionService, useFactory: (() => {
                        return {
                            bundle: ((bundleId) => mockLion),
                            ubercache: new Array(),
                            loadCbs: new Map<string, () => void>([])
                        };
                    })
                },
                { provide: IconService, useClass: MockIconService },
                { provide: SvgUtilService, useClass: MockSvgUtilService },
                { provide: TopologyService, useClass: MockTopologyService },
                { provide: 'Window', useValue: windowMock },
            ]
        })
        .compileComponents();
        logServiceSpy = TestBed.get(LogService);

        fixture = TestBed.createComponent(ForceSvgComponent);
        component = fixture.debugElement.componentInstance;
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('load sample files', () => {
        expect(openflowSampleData).toBeTruthy();
        expect(openflowSampleData.payload).toBeTruthy();
        expect(openflowSampleData.payload.id).toBe('(root)');

        expect(odtnSampleData).toBeTruthy();
        expect(odtnSampleData.payload).toBeTruthy();
        expect(odtnSampleData.payload.id).toBe('(root)');
    });

    it('should read sample data payload as Region', () => {
        expect(openflowRegionData).toBeTruthy();
        // console.log(regionData);
        expect(openflowRegionData.id).toBe('(root)');
        expect(openflowRegionData.devices).toBeTruthy();
        expect(openflowRegionData.devices.length).toBe(3);
        expect(openflowRegionData.devices[2].length).toBe(10);
        expect(openflowRegionData.hosts.length).toBe(3);
        expect(openflowRegionData.hosts[2].length).toBe(20);
        expect(openflowRegionData.links.length).toBe(44);
    });

    it('should read device246 correctly', () => {
        const device246: Device = openflowRegionData.devices[2][0];
        expect(device246.id).toBe('of:0000000000000246');
        expect(device246.nodeType).toBe('device');
        expect(device246.type).toBe('switch');
        expect(device246.online).toBe(true);
        expect(device246.master).toBe('10.192.19.68');
        expect(device246.layer).toBe('def');

        expect(device246.props.managementAddress).toBe('10.192.19.69');
        expect(device246.props.protocol).toBe('OF_13');
        expect(device246.props.driver).toBe('ofdpa-ovs');
        expect(device246.props.latitude).toBe('40.15');
        expect(device246.props.name).toBe('s246');
        expect(device246.props.locType).toBe('geo');
        expect(device246.props.channelId).toBe('10.192.19.69:59980');
        expect(device246.props.longitude).toBe('-121.679');

        expect(device246.location.locType).toBe('geo');
        expect(device246.location.latOrY).toBe(40.15);
        expect(device246.location.longOrX).toBe(-121.679);
    });

    it('should read host 3 correctly', () => {
        const host3: Host = openflowRegionData.hosts[2][0];
        expect(host3.id).toBe('00:88:00:00:00:03/110');
        expect(host3.nodeType).toBe('host');
        expect(host3.layer).toBe('def');
        expect(host3.configured).toBe(false);
        expect(host3.ips.length).toBe(3);
        expect(host3.ips[0]).toBe('fe80::288:ff:fe00:3');
        expect(host3.ips[1]).toBe('2000::102');
        expect(host3.ips[2]).toBe('10.0.1.2');
    });

    it('should read link 3-205 correctly', () => {
        const link3_205: Link = openflowRegionData.links[0];
        expect(link3_205.id).toBe('00:AA:00:00:00:03/None~of:0000000000000205/6');
        expect(link3_205.epA).toBe('00:AA:00:00:00:03/None');
        expect(link3_205.epB).toBe('of:0000000000000205');
        expect(String(LinkType[link3_205.type])).toBe('2');
        expect(link3_205.portA).toBe(undefined);
        expect(link3_205.portB).toBe('6');

        expect(link3_205.rollup).toBeTruthy();
        expect(link3_205.rollup.length).toBe(1);
        expect(link3_205.rollup[0].id).toBe('00:AA:00:00:00:03/None~of:0000000000000205/6');
        expect(link3_205.rollup[0].epA).toBe('00:AA:00:00:00:03/None');
        expect(link3_205.rollup[0].epB).toBe('of:0000000000000205');
        expect(String(LinkType[link3_205.rollup[0].type])).toBe('2');
        expect(link3_205.rollup[0].portA).toBe(undefined);
        expect(link3_205.rollup[0].portB).toBe('6');

    });

    it('should handle regionData change - empty Region', () => {
        component.ngOnChanges(
            {'regionData' : new SimpleChange(<Region>{}, emptyRegion, true)});

        expect(component.graph.nodes.length).toBe(0);
    });

    it('should know how to format names', () => {
        expect(ForceSvgComponent.extractNodeName('00:AA:00:00:00:03/None', undefined))
            .toEqual('00:AA:00:00:00:03/None');

        expect(ForceSvgComponent.extractNodeName('00:AA:00:00:00:03/161', '161'))
            .toEqual('00:AA:00:00:00:03');

        // Like epB of first example in sampleData file - endPtStr contains port number
        expect(ForceSvgComponent.extractNodeName('of:0000000000000206/6', '6'))
            .toEqual('of:0000000000000206');

        // Like epB of second example in sampleData file - endPtStr does not contain port number
        expect(ForceSvgComponent.extractNodeName('of:0000000000000206', '6'))
            .toEqual('of:0000000000000206');
    });

    it('should handle openflow regionData change - sample Region', () => {
        component.regionData = openflowRegionData;
        component.ngOnChanges(
            {'regionData' : new SimpleChange(<Region>{}, openflowRegionData, true)});

        expect(component.graph.nodes.length).toBe(30);

        expect(component.graph.links.length).toBe(44);

    });

    it('should handle odtn regionData change - sample odtn Region', () => {
        component.regionData = odtnRegionData;
        component.ngOnChanges(
            {'regionData' : new SimpleChange(<Region>{}, odtnRegionData, true)});

        expect(component.graph.nodes.length).toBe(2);

        expect(component.graph.links.length).toBe(6);

    });

    it('should handle highlights and match them to existing links', () => {
        component.regionData = topo2BaseRegionData;
        component.ngOnChanges(
            {'regionData' : new SimpleChange(<Region>{}, topo2BaseRegionData, true)});

        expect(component.graph.links.length).toBe(9);

        expect(linkHightlights.length).toBe(6);

        // should be able to find all of the highlighted links in the original data set
        linkHightlights.forEach((lh: LinkHighlight) => {
            const foundLink = component.graph.links.find((l: Link) => l.id === Link.linkIdFromShowHighlights(lh.id));
            expect(foundLink).toBeDefined();
        });
    });
});
