/*
 * 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 { Component, Input, Inject, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import {
    FnService,
    LoadingService,
    LogService,
    WebSocketService,
    SortDir, TableBaseImpl, TableResponse
} from 'gui2-fw-lib';

/**
 * Model of the response from the WebSocket
 */
export interface AlarmTableResponse extends TableResponse {
    alarmTables: Alarm[];
}

/**
 * Model of the alarms returned from the WebSocket
 */
export interface Alarm {
    id: string;
    alarmDesc: string;
    alarmDeviceId: string;
    alarmSource: string;
    alarmTimeRaised: string;
    alarmTimeUpdated: string;
    alarmTimeCleared: string;
    alarmSeverity: string;
}

export enum AlarmAction {
    NONE = 0,
    ACKNOWLEDGE = 1,
    CLEAR = 2,
}

/**
 * Model of the Control Button
 */
export interface CtrlBtnState {
    acknowledged: boolean;
    cleared: boolean;
    selection: string;
}

const ACKNOWLEDGED = 'ACKNOWLEDGED';
const CLEARED = 'CLEARED';

/**
* ONOS GUI -- Alarm Table Component extends TableBaseImpl
*/
@Component({
    selector: 'onos-alarmtable',
    templateUrl: './alarmtable.component.html',
    styleUrls: ['./alarmtable.component.css', '../../../fw/widget/table.css', '../../../fw/widget/table.theme.css']
})
export class AlarmTableComponent extends TableBaseImpl implements OnInit, OnDestroy {
    devId: string;
    selRowAlarmId: string;
    // TODO Add in LION translations
    acknowledgeTip: string = 'Acknowledge';
    clearTip: string = 'Clear';
    AlarmActionEnum: any = AlarmAction;
    alarmAction: AlarmAction = AlarmAction.NONE;
    confirmMsg: string = '';
    ctrlBtnState: CtrlBtnState;

    constructor(
        private route: ActivatedRoute,
        @Inject('Window') private w: any,
        protected log: LogService,
        protected ls: LoadingService,
        protected fs: FnService,
        protected wss: WebSocketService,
    ) {
        super(fs, ls, log, wss, 'alarmTable');

        this.route.queryParams.subscribe(params => {
            this.devId = params['devId'];

        });

        this.payloadParams = {
            devId: this.devId
        };

        this.responseCallback = this.alarmResponseCb;

        this.sortParams = {
            firstCol: 'alarmTimeRaised',
            firstDir: SortDir.desc,
            secondCol: 'alarmDeviceId',
            secondDir: SortDir.asc,
        };

        this.ctrlBtnState = <CtrlBtnState>{
            acknowledged: false,
            cleared: false
        };
        this.log.debug('AlarmTableComponent constructed');
    }

    ngOnInit() {
        this.init();
        this.log.debug('AlarmTableComponent initialized');
    }

    ngOnDestroy() {
        this.destroy();
        this.log.debug('AlarmTableComponent destroyed');
    }

    alarmResponseCb(data: AlarmTableResponse) {
        this.log.debug('Alarm response received for ', data.alarmTables.length, 'alarm');
    }

    rowSelection(event: any, selRow: any) {
        this.ctrlBtnState.acknowledged = this.selId && selRow && selRow.state === ACKNOWLEDGED;
        this.ctrlBtnState.cleared = this.selId && selRow && selRow.cleared === CLEARED;
        this.ctrlBtnState.selection = this.selId;
        this.selRowAlarmId = selRow.appId;
        this.log.debug('Row ', this.selId, 'selected', this.ctrlBtnState);
    }

    /**
     * Perform one of the alarm actions - acknowledge or clear
     * Raises a dialog which calls back the dOk() below
     */
    confirmAction(action: AlarmAction): void {
        this.alarmAction = action;
        const alarmActionLc = (<string>AlarmAction[this.alarmAction]).toLowerCase();

        this.confirmMsg = alarmActionLc + ' ' + this.selId + '?';

        this.log.debug('Initiating', this.alarmAction, 'of', this.selId);
    }

    /**
     * Callback when the Confirm dialog is shown and a choice is made
     */
    dOk(choice: boolean) {
        const alarmActionLc = (<string>AlarmAction[this.alarmAction]).toLowerCase();
        if (choice) {
            this.log.debug('Confirmed', alarmActionLc, 'on', this.selId);

            /** commented out until backend is implemented
            this.wss.sendEvent(APPMGMTREQ, {
                action: alarmActionLc,
                name: this.selId,
                sortCol: this.sortParams.firstCol,
                sortDir: SortDir[this.sortParams.firstDir],
            });

            this.wss.sendEvent(DETAILSREQ, { id: this.selId });
            */
        } else {
            this.log.debug('Cancelled', alarmActionLc, 'on', this.selId);
        }
        this.confirmMsg = '';
    }

    ackIcon(acknowledged: string): string {
        if (acknowledged === 'true') {
            return 'active';
        } else {
            return 'appInactive';
        }
    }
}
