/*
 * 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 = '../../ui/rs/applications/'; // TODO: This is a hack to work off GUIv1 URL
/** 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
        };
    }
}
