/*
 * 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

});
