/*
 * 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, OnInit, OnDestroy, Inject } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';

import { DialogService } from '../../../fw/layer/dialog.service';
import { FnService } from '../../../fw/util/fn.service';
import { IconService } from '../../../fw/svg/icon.service';
import { KeyService } from '../../../fw/util/key.service';
import { LionService } from '../../../fw/util/lion.service';
import { LoadingService } from '../../../fw/layer/loading.service';
import { LogService } from '../../../log.service';
import { TableBaseImpl, TableResponse, TableFilter, SortParams, SortDir } from '../../../fw/widget/table.base';
import { UrlFnService } from '../../../fw/remote/urlfn.service';
import { WebSocketService } from '../../../fw/remote/websocket.service';
import { TableFilterPipe } from '../../../fw/widget/tablefilter.pipe';

const INSTALLED = 'INSTALLED';
const ACTIVE = 'ACTIVE';
const APPMGMTREQ = 'appManagementRequest';
const DETAILSREQ = 'appDetailsRequest';
const FILEUPLOADURL = 'upload';
const FILEDOWNLOADURL = 'download';
const ACTIVATEOPTION = '?activate=true';
const DRAGDROPMSG1 = 'Drag and drop one file at a time';
const DRAGDROPMSGEXT = 'Only files ending in .oar can be dropped';

/** Prefix to access the REST service for applications */
export const APPURLPREFIX = 'rs/applications/';
/** Suffix to access the icon of the application - gives back an image */
export const ICONURLSUFFIX = '/icon';

const downloadSuffix = '/download';
const dialogId = 'app-dialog';
const dialogOpts = {
    edge: 'right',
    width: 400,
};
const strongWarning = {
    'org.onosproject.drivers': true,
};
const propOrder = ['id', 'state', 'category', 'version', 'origin', 'role'];

/**
 * Model of the data returned through the Web Socket about apps.
 */
interface AppTableResponse extends TableResponse {
    apps: App[];
}

/**
 * Model of the data returned through Web Socket for a single App
 */
export interface App {
    category: string;
    desc: string;
    features: string[];
    icon: string;
    id: string;
    origin: string;
    permissions: string[];
    readme: string;
    required_apps: string[];
    role: string;
    state: string;
    title: string;
    url: string;
    version: string;
    _iconid_state: string;
}

export enum AppAction {
    NONE = 0,
    ACTIVATE = 1,
    DEACTIVATE = 2,
    UNINSTALL = 3,
}

/**
 * Model of the Control Button
 */
interface CtrlBtnState {
    installed: boolean;
    selection: string;
    active: boolean;
}

/**
 * ONOS GUI -- Apps View Component extends TableBaseImpl
 */
@Component({
  selector: 'onos-apps',
  templateUrl: './apps.component.html',
  styleUrls: [
    './apps.component.css', './apps.theme.css',
    '../../../fw/widget/table.css', '../../../fw/widget/table.theme.css'
    ]
})
export class AppsComponent extends TableBaseImpl implements OnInit, OnDestroy {

    // deferred localization strings
    lionFn; // Function
    warnDeactivate: string;
    warnOwnRisk: string;
    ctrlBtnState: CtrlBtnState;
    appFile: any;

    uploadTip: string;
    activateTip: string;
    deactivateTip: string;
    uninstallTip: string;
    downloadTip: string;
    alertMsg: string;
    AppActionEnum: any = AppAction;
    appAction: AppAction = AppAction.NONE;
    confirmMsg: string = '';
    strongWarning: string = '';

    constructor(
        protected fs: FnService,
        private ds: DialogService,
        private is: IconService,
        private ks: KeyService,
        private lion: LionService,
        protected ls: LoadingService,
        protected log: LogService,
        private ufs: UrlFnService,
        protected wss: WebSocketService,
        @Inject('Window') private window: Window,
        private httpClient: HttpClient
    ) {
        super(fs, null, log, wss, 'app');
        this.responseCallback = this.appResponseCb;
        this.parentSelCb =  this.rowSelection;
        // pre-populate sort so active apps are at the top of the list
        this.sortParams = {
            firstCol: 'state',
            firstDir: SortDir.desc,
            secondCol: 'title',
            secondDir: SortDir.asc,
        };
        // We want doLion() to be called only after the Lion
        // service is populated (from the WebSocket)
        // If lion is not ready we make do with a dummy function
        // As soon a lion gets loaded this function will be replaced with
        // the real thing
        if (this.lion.ubercache.length === 0) {
            this.lionFn = this.dummyLion;
            this.lion.loadCbs.set('apps', () => this.doLion());
        } else {
            this.doLion();
        }

        this.ctrlBtnState = <CtrlBtnState>{
            installed: false,
            active: false
        };
    }

    /**
     * Initialize querying the WebSocket for App table details
     */
    ngOnInit() {
        this.init();
    }

    /**
     * Stop sending queries to WebSocket
     */
    ngOnDestroy() {
        this.lion.loadCbs.delete('apps');
        this.destroy();
        this.log.debug('AppComponent destroyed');
    }

    /**
     * The callback called when App data returns from WSS
     */
    appResponseCb(data: AppTableResponse) {
        this.log.debug('App response received for ', data.apps.length, 'apps');
    }

    /**
     * called when a row is selected - sets the state of control icons
     */
    rowSelection(event: any, selRow: any) {
        this.ctrlBtnState.installed = this.selId && selRow && selRow.state === INSTALLED;
        this.ctrlBtnState.active = this.selId && selRow && selRow.state === ACTIVE;
        this.ctrlBtnState.selection = this.selId;
        this.log.debug('Row ', this.selId, 'selected', this.ctrlBtnState);
    }


    /**
     * Perform one of the app actions - activate, deactivate or uninstall
     * Raises a dialog which calls back the dOk() below
     */
    confirmAction(action: AppAction): void {
        this.appAction = action;
        const appActionLc = (<string>AppAction[this.appAction]).toLowerCase();

        this.confirmMsg = this.lionFn(appActionLc) + ' ' + this.selId;
        if (strongWarning[this.selId]) {
            this.strongWarning = this.warnDeactivate + '\n' + this.warnOwnRisk;
        }

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

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

            this.wss.sendEvent(APPMGMTREQ, {
                action: appActionLc,
                name: this.selId,
                sortCol: this.sortParams.firstCol,
                sortDir: SortDir[this.sortParams.firstDir],
            });
            if (this.appAction === AppAction.UNINSTALL) {
                this.selId = '';
            } else {
                this.wss.sendEvent(DETAILSREQ, { id: this.selId });
            }

        } else {
            this.log.debug('Cancelled', appActionLc, 'on', this.selId);
        }
        this.confirmMsg = '';
        this.strongWarning = '';
    }

    downloadApp() {
        if (this.ctrlBtnState.selection) {
            (<any>this.window).location = APPURLPREFIX + this.selId + '/' + FILEDOWNLOADURL;
        }
    }

    /**
     * When the file is selected this fires
     * It passes the file on to the server through a POST request
     * If there is an error its logged and raised to the user through Flash Component
     */
    fileEvent(event: any, activateImmediately?: boolean) {
        this.log.debug('File event for', event.target.files[0]);
        const formData = new FormData();
        formData.append('file', event.target.files[0]);
        let url = APPURLPREFIX + FILEUPLOADURL;
        if (activateImmediately) {
            url += ACTIVATEOPTION;
        }
        this.httpClient
            .post<any>(APPURLPREFIX + FILEUPLOADURL, formData)
            .subscribe(
                data => this.log.debug(data),
                err => {
                    this.log.warn(err.message);
                    this.alertMsg = err.message; // This will activate flash msg
                }
            );

    }

    /**
     * When the upload button is clicked pass this on to the file input (hidden)
     */
    triggerForm() {
        document.getElementById('uploadFile')
                .dispatchEvent(new MouseEvent('click'));
    }

    /**
     * Read the LION bundle for App and set up the lionFn
     */
    doLion() {
        this.lionFn = this.lion.bundle('core.view.App');

        this.warnDeactivate = this.lionFn('dlg_warn_deactivate');
        this.warnOwnRisk = this.lionFn('dlg_warn_own_risk');

        this.uploadTip = this.lionFn('tt_ctl_upload');
        this.activateTip = this.lionFn('tt_ctl_activate');
        this.deactivateTip = this.lionFn('tt_ctl_deactivate');
        this.uninstallTip = this.lionFn('tt_ctl_uninstall');
        this.downloadTip = this.lionFn('tt_ctl_download');
    }

    onDrop(event: DragEvent) {
        event.preventDefault();
        event.stopPropagation();

        const dt = event.dataTransfer;
        const droppedFiles = dt.files;

        this.log.debug(droppedFiles.length, 'File(s) dropped');
        if (droppedFiles.length !== 1) {
            this.log.error(DRAGDROPMSG1, droppedFiles.length, 'were dropped');
            this.alertMsg = DRAGDROPMSG1;
            return;
        } else if (droppedFiles[0].name.slice(droppedFiles[0].name.length - 4) !== '.oar') {
            this.log.error(DRAGDROPMSGEXT, droppedFiles[0].name, 'rejected');
            this.alertMsg = DRAGDROPMSGEXT;
            return;
        }

        const fileEvent = {
            target: {
                files: droppedFiles
            }
        };
        this.fileEvent(fileEvent, true);
    }

    onDragOver(evt) {
        evt.preventDefault();
        evt.stopPropagation();
    }

    onDragLeave(evt) {
        evt.preventDefault();
        evt.stopPropagation();
    }

    deselectRow(event) {
        this.log.debug('Details panel close event');
        this.selId = event;
        this.ctrlBtnState = <CtrlBtnState>{
            installed: undefined,
            active: undefined
        };
    }
}
