/*
 * Copyright 2019-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, OnDestroy, OnInit } from '@angular/core';
import {
    FnService,
    LogService,
    PrefsService,
    WebSocketService,
    IconService,
    SortDir, TableBaseImpl, TableResponse
} from 'gui2-fw-lib';
import { ActivatedRoute } from '@angular/router';
import {FormGroup, FormControl} from '@angular/forms';

/**
 * Model of the response from WebSocket
 */
interface RoadmPortTableResponse extends TableResponse {
    roadmPorts: RoadmPort[];
}

/**
 * Model of the roadm ports returned from the WebSocket
 */
interface RoadmPort {
    id: string;
    reversePort: string;
    name: string;
    type: string;
    enabled: string;
    minFreq: string;
    maxFreq: string;
    grid: string;
    powerRange: string;
    currentPower: string;
    targetPower: string;
    modulation: string;
    hasTargetPower: string;
    serviceState: string;
}

interface FilterToggleState {
    devId: string;
    nzFilter: boolean;
    showDelta: boolean;
}

const defaultPortPrefsState = {
    nzFilter: 1,
    showDelta: 0,
};

/**
 * ONOS GUI -- Port View Component
 */
@Component({
    selector: 'roadm-port',
    templateUrl: './port.component.html',
    styleUrls: ['./port.component.css', '../../../fw/widget/table.css', '../../../fw/widget/table.theme.css']
})
export class RoadmPortComponent extends TableBaseImpl implements OnInit, OnDestroy {
    devId: string;
    nzFilter: boolean = true;
    showDelta: boolean = false;
    prefsState = {};
    toggleState: FilterToggleState;

    powerForm: FormGroup;
    modulationForm: FormGroup;
    SET_POWER_REQ = 'roadmSetTargetPowerRequest';
    SET_POWER_RESP = 'roadmSetTargetPowerResponse';
    SET_MODULATION = 'roadmSetModulationRequest';

    restorePrefsConfig; // Function

    deviceTip = 'Show device table';

    constructor(protected fs: FnService,
                protected log: LogService,
                protected ar: ActivatedRoute,
                protected wss: WebSocketService,
                protected prefs: PrefsService,
                protected is: IconService,
    ) {
        super(fs, log, wss, 'roadmPort');
        this.ar.queryParams.subscribe(params => {
            this.devId = params['devId'];

        });

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

        this.responseCallback = this.portResponseCb;
        this.restorePrefsConfig = this.restoreConfigFromPrefs;

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

        this.is.loadIconDef('switch');
    }

    ngOnInit() {
        this.init();
        this.createForm();
        this.wss.bindHandlers(new Map<string, (data) => void>([
            [this.SET_POWER_RESP, (data) => this.powerConfigCb(data)]
        ]));
        this.log.debug('RoadmPortComponent initialized');
    }

    createForm() {
        this.powerForm = new FormGroup({
            newPower: new FormControl(''),
        });
        this.modulationForm = new FormGroup({
            newModulation: new FormControl(''),
        });
        this.log.debug('Create Forms');
    }

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

    portResponseCb(data: RoadmPortTableResponse) {
        this.log.debug('Roadm Port response received for ', data.roadmPorts.length, 'port');
    }

    isNz(): boolean {
        return this.nzFilter;
    }

    isDelta(): boolean {
        return this.showDelta;
    }

    toggleNZState(b?: any) {
        if (b === undefined) {
            this.nzFilter = !this.nzFilter;
        } else {
            this.nzFilter = b;
        }
        this.payloadParams = this.filterToggleState();
        this.updatePrefsState('nzFilter', this.nzFilter);
        this.forceRefesh();
    }

    toggleDeltaState(b?: any) {
        if (b === undefined) {
            this.showDelta = !this.showDelta;
        } else {
            this.showDelta = b;
        }

        this.payloadParams = this.filterToggleState();
        this.updatePrefsState('showDelta', this.showDelta);
        this.forceRefesh();
    }

    updatePrefsState(what: any, b: any) {
        this.prefsState[what] = b ? 1 : 0;
        this.prefs.setPrefs('port_prefs', this.prefsState);
    }

    filterToggleState(): FilterToggleState {
        return this.toggleState = {
            devId: this.devId,
            nzFilter: this.nzFilter,
            showDelta: this.showDelta,
        };
    }

    forceRefesh() {
        this.requestTableData();
    }

    restoreConfigFromPrefs() {
        this.prefsState = this.prefs.asNumbers(
            this.prefs.getPrefs('port_prefs', defaultPortPrefsState, )
        );

        this.log.debug('Port - Prefs State:', this.prefsState);
        this.toggleDeltaState(this.prefsState['showDelta']);
        this.toggleNZState(this.prefsState['nzFilter']);
    }

    submitPower(devId, port) {
        this.log.debug('Set power of port ', port, 'in device ', devId, 'as value ', this.powerForm.value['newPower'], 'dBm.');
        this.wss.sendEvent(this.SET_POWER_REQ, {
            'targetPower': this.powerForm.value['newPower'],
            'devId': devId,
            'id': port,
        });
    }

    submitModulation(devId, port) {
        this.log.debug('Set Modulation of port ', port, 'in device ', devId, 'as value ', this.modulationForm.value['newModulation']);
        this.wss.sendEvent(this.SET_MODULATION, {
            'modulation': this.modulationForm.value['newModulation'],
            'devId': devId,
            'id': port,
        });
    }

    powerConfigCb(data) {
        if (!data.valid) {
            const info = 'The power config operation is failed. The reason is: \n' + data.message;
            alert(info);
        } else {
            this.log.debug('The power config operation is successful!');
        }
    }

    convertNumber(str: string): number {
        return Number(str);
    }
}
