/*
 * 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 { FnService } from '../util/fn.service';
import { LoadingService } from '../layer/loading.service';
import { LogService } from '../../log.service';
import { WebSocketService } from '../remote/websocket.service';
import { Observable, of } from 'rxjs';

const REFRESH_INTERVAL = 2000;
const SEARCH_REGEX = '\\W';

/**
 * Model of table annotations within this table base class
 */
interface TableAnnots {
    noRowsMsg: string;
}

/**
 * A model of data returned from Web Socket in a TableResponse
 *
 * There is an interface extending from this one in the parent component
 */
export interface TableResponse {
    annots: any;
    // There will be other parts to the response depending on table type
    // Expect one called tag+'s' e.g. devices or apps
}

/**
 * A criteria for filtering the tableData
 */
export interface TableFilter {
    queryStr: string;
    queryBy: string;
    sortBy: string;
}

/**
 * Enumerated values for the sort dir
 */
export enum SortDir {
    asc = 'asc', desc = 'desc'
}

/**
 * A structure to format sort params for table
 * This is sent to WebSocket as part of table request
 */
export interface SortParams {
    firstCol: string;
    firstDir: SortDir;
    secondCol: string;
    secondDir: SortDir;
}

/**
 * ONOS GUI -- Widget -- Table Base class
 */
export abstract class TableBaseImpl {
    // attributes from the interface
    protected annots: TableAnnots;
    protected changedData: string[] = [];
    protected payloadParams: any;
    protected sortParams: SortParams;
    protected selectCallback; // Function
    protected parentSelCb = null;
    protected responseCallback; // Function
    selId: string = undefined;
    tableData: any[] = [];
    tableDataFilter: TableFilter;
    toggleRefresh; // Function
    autoRefresh: boolean = true;
    autoRefreshTip: string = 'Toggle auto refresh'; // TODO: get LION string

    private root: string;
    private req: string;
    private resp: string;
    private refreshPromise: any = null;
    private handlers: string[] = [];

    constructor(
        protected fs: FnService,
        protected ls: LoadingService,
        protected log: LogService,
        protected wss: WebSocketService,
        protected tag: string,
        protected idKey: string = 'id',
        protected selCb = () => ({}) // Function
    ) {
        this.root = tag + 's';
        this.req = tag + 'DataRequest';
        this.resp = tag + 'DataResponse';

        this.selectCallback = this.rowSelectionCb;
        this.toggleRefresh = () => {
            this.autoRefresh = !this.autoRefresh;
            this.autoRefresh ? this.startRefresh() : this.stopRefresh();
        };

        // Mapped to the search and searchBy inputs in template
        // Changes are handled through TableFilterPipe
        this.tableDataFilter = <TableFilter>{
            queryStr: '',
            queryBy: '$',
        };
    }

    init() {
        this.wss.bindHandlers(new Map<string, (data) => void>([
            [this.resp, (data) => this.tableDataResponseCb(data)]
        ]));
        this.handlers.push(this.resp);

        this.annots = <TableAnnots>{
            noRowsMsg: ''
        };

        // Now send the WebSocket request and make it repeat every 2 seconds
        this.requestTableData();
        this.startRefresh();
        this.log.debug('TableBase initialized. Calling ', this.req,
            'every', REFRESH_INTERVAL, 'ms');
    }

    destroy() {
        this.wss.unbindHandlers(this.handlers);
        this.stopRefresh();
        this.ls.stop();
    }

    /**
     * A callback that executes when the table data that was requested
     * on WebSocketService arrives.
     *
     * Happens every 2 seconds
     */
    tableDataResponseCb(data: TableResponse) {
        this.ls.stop();

        const newTableData: any[] = Array.from(data[this.root]);
        this.annots.noRowsMsg = data.annots.no_rows_msg;

        // If the parents onResp() function is set then call it
        if (this.responseCallback) {
            this.responseCallback(data);
        }
        this.changedData = [];

        // checks if data changed for row flashing
        if (JSON.stringify(newTableData) !== JSON.stringify(this.tableData)) {
            this.log.debug('table data has changed');
            const oldTableData: any[] = this.tableData;
            this.tableData = [ ...newTableData ]; // ES6 spread syntax
            // only flash the row if the data already exists
            if (oldTableData.length > 0) {
                for (const idx in newTableData) {
                    if (!this.fs.containsObj(oldTableData, newTableData[idx])) {
                        this.changedData.push(newTableData[idx][this.idKey]);
                    }
                }
            }
        }
    }

    /**
     * Table Data Request
     * Pass in sort parameters and the set will be returned sorted
     * In the old GUI there was also a query parameter, but this was not
     * implemented on the server end
     */
    requestTableData() {
        const p = Object.assign({}, this.sortParams, this.payloadParams);

        // Allow it to sit in pending events
        if (this.wss.isConnected()) {
            if (this.fs.debugOn('table')) {
                this.log.debug('Table data REQUEST:', this.req, p);
            }
            this.wss.sendEvent(this.req, p);
            this.ls.start();
        }
    }

    /**
     * Row Selected
     */
    rowSelectionCb(event: any, selRow: any): void {
        const selId: string = selRow[this.idKey];
        this.selId = (this.selId === selId) ? undefined : selId;
        this.log.debug('Row', selId, 'selected');
        if (this.parentSelCb) {
            this.parentSelCb(event, selRow);
        }
    }

    /**
     * autoRefresh functions
     */
    startRefresh() {
        this.refreshPromise =
            setInterval(() => {
                if (!this.ls.waiting()) {
                    if (this.fs.debugOn('table')) {
                        this.log.debug('Refreshing ' + this.root + ' page');
                    }
                    this.requestTableData();
                }
            }, REFRESH_INTERVAL);
    }

    stopRefresh() {
        if (this.refreshPromise) {
            clearInterval(this.refreshPromise);
            this.refreshPromise = null;
        }
    }

    isChanged(id: string): boolean {
        return (this.fs.inArray(id, this.changedData) === -1) ? false : true;
    }

    /**
     * A dummy implementation of the lionFn until the response is received and the LION
     * bundle is received from the WebSocket
     */
    dummyLion(key: string): string {
        return '%' + key + '%';
    }

    /**
     * Change the sort order of the data returned
     *
     * sortParams are passed to the server by WebSocket and the data is
     * returned sorted
     *
     * This is usually assigned to the (click) event on a column, and the column
     * name passed in e.g. (click)="onSort('origin')
     * If the column that is passed in is already the firstCol, then reverse its direction
     * If a new column is passed in, then make the existing col the 2nd sort order
     */
    onSort(colName: string) {
        if (this.sortParams.firstCol === colName) {
            if (this.sortParams.firstDir === SortDir.desc) {
                this.sortParams.firstDir = SortDir.asc;
                return;
            } else {
                this.sortParams.firstDir = SortDir.desc;
                return;
            }
        } else {
            this.sortParams.secondCol = this.sortParams.firstCol;
            this.sortParams.secondDir = this.sortParams.firstDir;
            this.sortParams.firstCol = colName;
            this.sortParams.firstDir = SortDir.desc;
        }
        this.log.debug('Sort params', this.sortParams);
        this.requestTableData();
    }

    sortIcon(column: string): string {
        if (this.sortParams.firstCol === column) {
            if (this.sortParams.firstDir === SortDir.asc) {
                return 'upArrow';
            } else {
                return 'downArrow';
            }
        } else {
            return '';
        }
    }
}
