/*
 * 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 { 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
 */
export 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;
}

export interface PayloadParams {
    devId: string;
}


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

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

    protected constructor(
        protected fs: FnService,
        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.loadingIconShown = false;
    }

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

        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.loadingIconShown = true;
        }
    }

    /**
     * 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.loadingIconShown) {
                    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 '';
        }
    }

    /**
     * De-selects the row
     */
    deselectRow(event) {
        this.log.debug('Details panel close event');
        this.selId = event;
    }
}
