/* eslint-disable security/detect-object-injection */
/*
 Copyright 2020 TATA ELXSI

 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.

 Author: BARATH KUMAR R (barath.r@tataelxsi.co.in)
*/

/**
 * @file Page for Operational View Component
 */
import { Component, Injector, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { CONSTANTNUMBER, ERRORDATA } from 'CommonModel';
import { environment } from 'environment';
import * as HttpStatus from 'http-status-codes';
import { OperationalViewAppActionsComponent } from 'OperationalAppActionsComponent';
import { OperationalViewAppConfigsComponent } from 'OperationalAppConfigsComponent';
import { OperationalViewAppExecutedActionsComponent } from 'OperationalAppExecutedActionsComponent';
import { EXECUTEDACTIONS, MACHINES, SET_TIMER, SETMODELS, SETTIMER, VCAAPPLICATIONS, VCADETAILS, VCASTATUS, VCAUNITS } from 'OperationalModel';
import { RestService } from 'RestService';
import { Observable } from 'rxjs';
import { Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { SharedService, isNullOrUndefined } from 'SharedService';
/**
 * Creating component
 * @Component takes OperationalViewComponent.html as template url
 */
@Component({
    selector: 'app-operational-view',
    templateUrl: './OperationalViewComponent.html'
})
/** Exporting a class @exports OperationalViewComponent */
export class OperationalViewComponent implements OnInit {
    /** Invoke service injectors @public */
    public injector: Injector;

    /** Check the loading results @public */
    public isLoadingResults: boolean = false;

    /** Give the message for the loading @public */
    public message: string = 'PLEASEWAIT';

    /** Formation of appropriate Data for vcaStatus Details @public */
    public vcaDetails: VCADETAILS[] = [];

    /** Contains all methods related to shared @public */
    public sharedService: SharedService;

    /** Utilizes rest service for any CRUD operations @public */
    public restService: RestService;

    /** variables contains activeID @public */
    public activeID: string = null;

    /** variables contains NS Instances ID @public */
    public instancesID: string = null;

    /** variables contains URL of operational Dashboard @public */
    public openURL: string = 'instances/operational-view/';

    /** variables contains default seconds for the timeout @public */
    public timeOutDefaultSeconds: number = CONSTANTNUMBER.timeOutDefaultSeconds;

    /** variables contains minimum seconds for the timeout @public */
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    public minSeconds: number = 5;

    /** variables contains maximum seconds for the timeout @public */
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    public maxSeconds: number = 60;

    /** variables contains timer calculation value of milliseconds @public */
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    public timeDefaultCal: number = 1000;

    /** variables contains timeout @public */
    public timeOut: number;

    /** Set the timer button @public */
    // eslint-disable-next-line no-magic-numbers
    public setSeconds: SETTIMER[] = SET_TIMER;

    /** Instance of subscriptions @private */
    private generateDataSub: Subscription;

    /** Contains tranlsate instance @private */
    private translateService: TranslateService;

    /** Holds teh instance of AuthService class of type AuthService @private */
    private activatedRoute: ActivatedRoute;

    /** Instance of the modal service @private */
    private modalService: NgbModal;

    /** creates Operational view component */
    constructor(injector: Injector) {
        this.injector = injector;
        this.restService = this.injector.get(RestService);
        this.sharedService = this.injector.get(SharedService);
        this.translateService = this.injector.get(TranslateService);
        this.activatedRoute = this.injector.get(ActivatedRoute);
        this.modalService = this.injector.get(NgbModal);
    }

    /**
     * Lifecyle Hooks the trigger before component is instantiate
     */
    public ngOnInit(): void {
        this.instancesID = this.activatedRoute.snapshot.paramMap.get('id');
        this.generateData();
        this.generateDataSub = this.sharedService.dataEvent.subscribe((): void => { this.generateData(); });
    }
    /** Fetching the juju vca_status data from API and Load it in the respective table @public */
    public generateData(): void {
        this.clearTimeoutAndInterval();
        this.modalService.dismissAll();
        this.isLoadingResults = true;
        this.vcaDetails = [];
        let NSURL: string = environment.NSDINSTANCES_URL;
        if (this.instancesID !== null) {
            NSURL = NSURL + '/' + this.instancesID;
            this.generateIndividualNSData(NSURL);
        } else {
            this.generateAllNSData(NSURL);
        }
    }
    /**
     * Show all NS Data that contains the juju vca_status from API and Load it in the table @public
     * @param NSURL : osm/nslcm/v1/ns_instances
     */
    public generateAllNSData(NSURL: string): void {
        this.restService.getResource(NSURL).subscribe((operationalList: VCASTATUS[]): void => {
            if (operationalList.length > 0) {
                operationalList.forEach((list: VCASTATUS): void => {
                    if (!isNullOrUndefined(list.vcaStatus)) {
                        const getVCAStatusDetails: VCADETAILS = this.vcaDetailsData(list, false, this.timeOutDefaultSeconds);
                        this.vcaDetails.push(getVCAStatusDetails);
                    }
                });
                if (this.activeID === null && this.vcaDetails.length > 0) {
                    this.activeID = this.vcaDetails[0].ns_id;
                }
            }
            this.isLoadingResults = false;
        }, (error: ERRORDATA): void => {
            this.isLoadingResults = false;
            this.restService.handleError(error, 'get');
        });
    }
    /**
     * Show the individual NS Data that contains the juju vca_status from generateNSData method and Load it in the table @public
     * @param NSURL : osm/nslcm/v1/ns_instances/<ID>
     */
    public generateIndividualNSData(NSURL: string): void {
        this.generateNSData(NSURL, false, this.timeOutDefaultSeconds).subscribe((getVCAStatusDetails: VCADETAILS): void => {
            this.vcaDetails.push(getVCAStatusDetails);
            if (this.activeID === null && this.vcaDetails.length > 0) {
                this.activeID = this.instancesID;
            }
            this.isLoadingResults = false;
        }, (error: ERRORDATA): void => {
            this.isLoadingResults = false;
            this.restService.handleError(error, 'get');
        });
    }
    /**
     * Fetching the Individual NS Data that contains the juju vca_status from API and return the VCADetails @public
     * @param NSURL : osm/nslcm/v1/ns_instances/<ID>
     * @param liveData : Needs to repeat the httprequest
     * @param timeOutSeconds : set the timeout seconds to trigger the httprequest
     */
    public generateNSData(NSURL: string, liveData: boolean, timeOutSeconds: number): Observable<VCADETAILS> {
        if (liveData) {
            NSURL = NSURL + '?vcaStatusRefresh=true';
        }
        return this.restService.getResource(NSURL).pipe(map((operationalList: VCASTATUS): VCADETAILS => this.vcaDetailsData(operationalList, liveData, timeOutSeconds)));
    }
    /**
     * Form the VCA Details for each NS Instances
     */
    public formVCADetails(getData: VCADETAILS): VCADETAILS {
        return {
            isLiveloading: getData.isLiveloading,
            ns_id: getData.ns_id,
            vcaStatusModels: getData.vcaStatusModels,
            timeOutSeconds: getData.timeOutSeconds,
            vca_id: getData.vca_id,
            vca_name: getData.vca_name
        };
    }
    /**
     * Assign the VCA Status of Multiple model in getModels array for each NS Instance
     */
    public assignVCAStatusOfEachModel(getData: SETMODELS): SETMODELS {
        return {
            applications: getData.applications,
            branches: getData.branches,
            controller_timestamp: getData.controller_timestamp,
            executedActions: getData.executedActions,
            machines: getData.machines,
            model: getData.model,
            offers: getData.offers,
            relations: getData.relations,
            remote_applications: getData.remote_applications,
            units: getData.units,
            unknown_fields: getData.unknown_fields
        };
    }
    /**
     * Use to fetch the vcaDetails from vca_status @public
     */
    public vcaDetailsData(list: VCASTATUS, liveData: boolean, timeOutSeconds: number): VCADETAILS {
        const assignVCADetails: VCADETAILS[] = [];
        const setModels: SETMODELS[] = [];
        Object.keys(list.vcaStatus).forEach((key: string): void => {
            const vcaApplication: VCAAPPLICATIONS[] = this.appData(list.vcaStatus[key].applications);
            const vcaUnits: VCAUNITS[] = this.unitsData(vcaApplication);
            const vcaMachines: MACHINES[] = this.machinesData(list.vcaStatus[key].machines);
            const assignNSInstancesID: string = key;
            list.vcaStatus[key].units = vcaUnits;
            list.vcaStatus[key].applications = vcaApplication;
            list.vcaStatus[key].machines = vcaMachines;
            // eslint-disable-next-line no-self-assign
            list.vcaStatus[key].relations = list.vcaStatus[key].relations;
            // eslint-disable-next-line no-self-assign
            list.vcaStatus[key].model = list.vcaStatus[key].model;
            const getEachModelData: SETMODELS = this.assignVCAStatusOfEachModel(list.vcaStatus[key]);
            setModels.push(getEachModelData);
            list.vcaStatus[assignNSInstancesID].vca_id = key;
            list.vcaStatus[assignNSInstancesID].vca_name = list.name;
            list.vcaStatus[assignNSInstancesID].ns_id = list.id;
            list.vcaStatus[assignNSInstancesID].isLiveloading = liveData;
            list.vcaStatus[assignNSInstancesID].timeOutSeconds = timeOutSeconds;
            list.vcaStatus[assignNSInstancesID].vcaStatusModels = setModels;
            const getAssignedData: VCADETAILS = this.formVCADetails(list.vcaStatus[assignNSInstancesID]);
            assignVCADetails.push(getAssignedData);
        });
        return assignVCADetails[0];
    }
    /**
     * Use to fetch the app data from vca_status @public
     */
    public appData(applicationData: VCAAPPLICATIONS): VCAAPPLICATIONS[] {
        const vcaApplication: VCAAPPLICATIONS[] = [];
        Object.keys(applicationData).forEach((applicationKey: string): void => {
            const charmSplitlist: string[] = applicationData[applicationKey].charm.split('/');
            const status: string = applicationData[applicationKey].status.status;
            // eslint-disable-next-line deprecation/deprecation
            const charm: string = charmSplitlist[1].substr(0, charmSplitlist[1].lastIndexOf('-'));
            // eslint-disable-next-line deprecation/deprecation
            const store: string = charmSplitlist[0].substr(0, charmSplitlist[0].lastIndexOf(':'));
            applicationData[applicationKey].app_id = applicationKey;
            applicationData[applicationKey].charm = charm;
            applicationData[applicationKey].status = status;
            applicationData[applicationKey].scale = Object.keys(applicationData[applicationKey].units).length;
            applicationData[applicationKey].store = store;
            applicationData[applicationKey].configs = !isNullOrUndefined(applicationData[applicationKey].configs) ?
                applicationData[applicationKey].configs : null;
            applicationData[applicationKey].actions = !isNullOrUndefined(applicationData[applicationKey].actions) ?
                applicationData[applicationKey].actions : null;
            vcaApplication.push(applicationData[applicationKey]);
        });
        return vcaApplication;
    }
    /**
     * Use to fetch the units data from vca_status @public
     */
    public unitsData(applicationData: VCAAPPLICATIONS[]): VCAUNITS[] {
        const vcaUnits: VCAUNITS[] = [];
        applicationData.forEach((applicationList: VCAAPPLICATIONS): void => {
            Object.keys(applicationList.units).forEach((unitsKey: string): void => {
                applicationList.units[unitsKey].unit_id = unitsKey;
                vcaUnits.push(applicationList.units[unitsKey]);
            });
        });
        return vcaUnits;
    }
    /**
     * Use to fetch the machines data from vca_status @public
     */
    public machinesData(machinesData: MACHINES[]): MACHINES[] {
        const vcaMachines: MACHINES[] = [];
        Object.keys(machinesData).forEach((machineKey: string): void => {
            vcaMachines.push(machinesData[machineKey]);
        });
        return vcaMachines;
    }
    /** Show the Config list in modal using modalservice @public */
    public showExecutedActionsList(executeActionsList: EXECUTEDACTIONS[]): void {
        // eslint-disable-next-line security/detect-non-literal-fs-filename
        this.modalService.open(OperationalViewAppExecutedActionsComponent, { size: 'xl', backdrop: 'static' })
            .componentInstance.params = { executedActions: executeActionsList };
    }
    /** Show the Config list in modal using modalservice @public */
    public showConfigList(configList: object): void {
        // eslint-disable-next-line security/detect-non-literal-fs-filename
        this.modalService.open(OperationalViewAppConfigsComponent, { size: 'xl', backdrop: 'static' })
            .componentInstance.params = { configs: configList };
    }
    /** Show the Config list in modal using modalservice @public */
    public showActionsList(actionsList: object): void {
        // eslint-disable-next-line security/detect-non-literal-fs-filename
        this.modalService.open(OperationalViewAppActionsComponent, { size: 'xl', backdrop: 'static' })
            .componentInstance.params = { actions: actionsList };
    }
    /** Call the live data to fetch the latest results @public */
    public callLiveData(isChecked: boolean, getNSID: string, index: number): void {
        this.vcaDetails[index].isLiveloading = isChecked;
        if (isChecked) {
            this.stopExistingModelLiveLoading(getNSID);
            this.generateRefreshedData(getNSID, index, this.vcaDetails[index].timeOutSeconds);
        } else {
            this.clearTimeoutAndInterval();
        }
    }
    /** Fetching the juju vca_status data from API and Load it in the respective model @public */
    public generateRefreshedData(getNSID: string, index: number, secondsValue: number): void {
        this.modalService.dismissAll();
        const liveDataURL: string = environment.NSDINSTANCES_URL + '/' + getNSID;
        this.generateNSData(liveDataURL, true, secondsValue).subscribe((getVCAStatusDetails: VCADETAILS): void => {
            this.vcaDetails[index] = getVCAStatusDetails;
            this.callSetTimeOut(getNSID, index, secondsValue);
        }, (error: ERRORDATA): void => {
            this.restService.handleError(error, 'get');
            if (error.error.status === HttpStatus.NOT_FOUND) {
                this.vcaDetails.splice(index, 1);
            }
            this.clearTimeoutAndInterval();
        });
    }
    /** Call the setimeout to refresh the all models data in regular timeout @public */
    public callSetTimeOut(id: string, index: number, secondsValue: number): void {
        this.clearTimeoutAndInterval();
        this.timeOut = window.setTimeout((): void => {
            this.generateRefreshedData(id, index, secondsValue);
        }, secondsValue * this.timeDefaultCal);
    }
    /** Stop existing model live reload @public */
    public stopExistingModelLiveLoading(getNSID: string): void {
        this.clearTimeoutAndInterval();
        this.vcaDetails.forEach((vcaDetail: VCADETAILS, i: number): void => {
            if (vcaDetail.ns_id !== getNSID) {
                vcaDetail.isLiveloading = false;
            }
        });
    }
    /** Method to show/hide the tables @public */
    public showHideTables(event: HTMLElement, getTableName: string, index: number): void {
        let selectedClassName: string = getTableName + index;
        if (selectedClassName === 'all' + index) {
            selectedClassName = '';
        }
        document.querySelectorAll('.filter' + index).forEach((button: HTMLElement): void => {
            button.classList.remove('active');
            if (selectedClassName !== '') {
                if (button.classList.contains(selectedClassName)) {
                    button.classList.add('active');
                }
            } else if (button.classList.contains('all' + index)) {
                button.classList.add('active');
            }
        });
        document.querySelectorAll('.filterTable' + index).forEach((table: HTMLElement): void => {
            table.classList.remove('hide');
            if (selectedClassName !== '') {
                if (!table.classList.contains(selectedClassName)) {
                    table.classList.add('hide');
                }
            }
        });
    }
    /** Get the timer selected @public */
    public onSetTimerSelector(getSeconds: number, nsID: string, index: number): void {
        this.vcaDetails[index].timeOutSeconds = getSeconds;
        this.callLiveData(true, nsID, index);
    }
    /** Clear settimeOut and setinterval @public */
    public clearTimeoutAndInterval(): void {
        clearTimeout(this.timeOut);
    }
    /**
     * Lifecyle hook which get trigger on component destruction
     */
    public ngOnDestroy(): void {
        this.clearTimeoutAndInterval();
        this.generateDataSub.unsubscribe();
    }
}
