/*
 * 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 '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();
        });
    });
});
