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

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