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

import { LogService } from '../../../../app/log.service';
import { WebSocketService, WsOptions, Callback, EventType } from '../../../../app/fw/remote/websocket.service';
import { FnService } from '../../../../app/fw/util/fn.service';
import { GlyphService } from '../../../../app/fw/svg/glyph.service';
import { ActivatedRoute, Params } from '@angular/router';
import { UrlFnService } from '../../../../app/fw/remote/urlfn.service';
import { WSock } from '../../../../app/fw/remote/wsock.service';
import { of } from 'rxjs';

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

class MockGlyphService {}

/**
 * ONOS GUI -- Remote -- Web Socket Service - Unit Tests
 */
describe('WebSocketService', () => {
    let wss: WebSocketService;
    let fs: FnService;
    let ar: MockActivatedRoute;
    let windowMock: Window;
    let logServiceSpy: jasmine.SpyObj<LogService>;

    const noop = () => ({});
    const send = jasmine.createSpy('send')
        .and.callFake((ev) => ev);
    const mockWebSocket = {
        send: send,
        onmessage: (msgEvent) => ({}),
        onopen: () => ({}),
        onclose: () => ({}),
    };

    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'
            }
        };
        fs = new FnService(ar, logSpy, windowMock);

        TestBed.configureTestingModule({
            providers: [WebSocketService,
                { provide: FnService, useValue: fs },
                { provide: LogService, useValue: logSpy },
                { provide: GlyphService, useClass: MockGlyphService },
                { provide: UrlFnService, useValue: new UrlFnService(logSpy, windowMock) },
                { provide: 'Window', useFactory: (() => windowMock ) },
                { provide: WSock, useFactory: (() => {
                        return {
                            newWebSocket: (() => mockWebSocket)
                        };
                    })
                }
            ]
        });

        wss = TestBed.get(WebSocketService);
        logServiceSpy = TestBed.get(LogService);
    });

    it('should define WebSocketService', () => {
        expect(wss).toBeDefined();
    });

    it('should define api functions', () => {
        expect(fs.areFunctions(wss, ['bootstrap', 'error',
            'handleOpen', 'handleMessage', 'handleClose',
            'findGuiSuccessor', 'informListeners', 'send',
            'noHandlersWarn', 'resetState',
            'createWebSocket', 'bindHandlers', 'unbindHandlers',
            'addOpenListener', 'removeOpenListener', 'sendEvent',
            'setVeilDelegate', 'setLoadingDelegate', 'isConnected', 'closeWebSocket'
        ])).toBeTruthy();
    });

    it('should use the appropriate URL, createWebsocket', () => {
        const url = wss.createWebSocket();
        expect(url).toEqual('ws://foo:80/onos/ui/websock/core');
    });

    it('should use the appropriate URL with modified port, createWebsocket',
        () => {
            const url = wss.createWebSocket(<WsOptions>{ wsport: 1243 });
            expect(url).toEqual('ws://foo:1243/onos/ui/websock/core');
    });

    it('should verify websocket event handlers, createWebsocket', () => {
        wss.createWebSocket({ wsport: 1234 });
        expect(fs.isF(mockWebSocket.onopen)).toBeTruthy();
        expect(fs.isF(mockWebSocket.onmessage)).toBeTruthy();
        expect(fs.isF(mockWebSocket.onclose)).toBeTruthy();
    });

    it('should invoke listener callbacks when websocket is up, handleOpen',
        () => {
            let num = 0;
            function incrementNum(host: string, url: string) {
                expect(host).toEqual('foo');
                num++;
            }
            wss.addOpenListener(incrementNum);
            wss.createWebSocket({ wsport: 1234 });

            mockWebSocket.onopen();
            expect(num).toBe(1);
    });

    it('should send pending events, handleOpen', () => {
        const fakeEvent = {
            event: 'mockEv',
            payload: { mock: 'thing' }
        };
        wss.sendEvent(fakeEvent.event, fakeEvent.payload);
        // on opening the socket, a single authentication event should have
        // been sent already...
        expect(mockWebSocket.send.calls.count()).toEqual(1);

        wss.createWebSocket({ wsport: 1234 });
        mockWebSocket.onopen();
        expect(mockWebSocket.send).toHaveBeenCalledWith(JSON.stringify(fakeEvent));
    });

    it('should handle an incoming bad JSON message, handleMessage', () => {
        const badMsg = {
            data: 'bad message'
        };
        wss.createWebSocket({ wsport: 1234 });
        expect(mockWebSocket.onmessage(badMsg)).toBeNull();
        expect(logServiceSpy.error).toHaveBeenCalled();
    });

    it('should verify message was handled, handleMessage', () => {
        let num = 0;
        function fakeHandler(data1: Object) { num++; }
        const data = JSON.stringify(<EventType>{
            event: 'mockEvResp',
            payload: {}
        });
        const event = {
            data: data
        };

        wss.createWebSocket({ wsport: 1234 });
        wss.bindHandlers(new Map<string, (data) => void>([
            ['mockEvResp', (data2) => fakeHandler(data2)]
        ]));
        expect(mockWebSocket.onmessage(event)).toBe(undefined);
        expect(num).toBe(1);
    });

    it('should warn if there is an unhandled event, handleMessage', () => {
        const data = { foo: 'bar', bar: 'baz'};
        const dataString = JSON.stringify(data);
        const badEv = {
                data: dataString
            };
        wss.createWebSocket({ wsport: 1234 });
        mockWebSocket.onmessage(badEv);
        expect(logServiceSpy.warn).toHaveBeenCalledWith('Unhandled event:', data);
    });

    it('should not warn if valid input, bindHandlers', () => {
        expect(wss.bindHandlers(new Map<string, (data) => void>([
            ['test', noop ],
            ['bar', noop ]
        ]))).toBe(undefined);

        expect(logServiceSpy.warn).not.toHaveBeenCalled();
    });

    it('should warn if no arguments, bindHandlers', () => {
        expect(wss.bindHandlers(
            new Map<string, (data) => void>([])
        )).toBeNull();
        expect(logServiceSpy.warn).toHaveBeenCalledWith(
            'WSS.bindHandlers(): no event handlers'
        );
    });

    it('should warn if duplicate handlers were given, bindHandlers',
        () => {
            wss.bindHandlers(
                new Map<string, (data) => void>([
                    ['noop', noop ]
                ])
            );
            expect(wss.bindHandlers(
                new Map<string, (data) => void>([
                    ['noop', noop ]
                ])
            )).toBe(undefined);
            expect(logServiceSpy.warn).toHaveBeenCalledWith('duplicate bindings ignored:',
                                                    ['noop']);
    });

    it('should warn if no arguments, unbindHandlers', () => {
        expect(wss.unbindHandlers([])).toBeNull();
        expect(logServiceSpy.warn).toHaveBeenCalledWith(
            'WSS.unbindHandlers(): no event handlers'
        );
    });
    // Note: cannot test unbindHandlers' forEach due to it using closure variable

    it('should not warn if valid argument, addOpenListener', () => {
        let o = wss.addOpenListener(noop);
        expect(o.id === 1);
        expect(o.cb === noop);
        expect(logServiceSpy.warn).not.toHaveBeenCalled();
        o = wss.addOpenListener(noop);
        expect(o.id === 2);
        expect(o.cb === noop);
        expect(logServiceSpy.warn).not.toHaveBeenCalled();
    });

    it('should log error if callback not a function, addOpenListener',
        () => {
            const o = wss.addOpenListener(null);
            expect(o.id === 1);
            expect(o.cb === null);
            expect(o.error === 'No callback defined');
            expect(logServiceSpy.error).toHaveBeenCalledWith(
                'WSS.addOpenListener(): callback not a function'
            );
    });

    it('should not warn if valid listener object, removeOpenListener', () => {
        expect(wss.removeOpenListener(<Callback>{
            id: 1,
            error: 'error',
            cb: noop
        })).toBe(undefined);
        expect(logServiceSpy.warn).not.toHaveBeenCalled();
    });

    it('should warn if listener is invalid, removeOpenListener', () => {
        expect(wss.removeOpenListener(<Callback>{})).toBeNull();
        expect(logServiceSpy.warn).toHaveBeenCalledWith(
            'WSS.removeOpenListener(): invalid listener', {}
        );
    });

    // Note: handleClose is not currently tested due to all work it does relies
    //       on closure variables that cannot be mocked

});
