/*
 * 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;
    currFreq: 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);
    }
}
