/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * 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.
 */

/*
 ONOS GUI -- App View Module
 */

(function () {
    'use strict';

    // injected refs
    var $log, $scope, wss, fs, ks, ps, is;

    // internal state
    var detailsPanel,
        pStartY,
        pHeight,
        top,
        middle,
        bottom,
        wSize = false,
        activateImmediately;

    // constants
    var INSTALLED = 'INSTALLED',
        ACTIVE = 'ACTIVE',
        appMgmtReq = 'appManagementRequest',
        topPdg = 60,
        panelWidth = 540,
        pName = 'application-details-panel',
        detailsReq = 'appDetailsRequest',
        detailsResp = 'appDetailsResponse',
        fileUploadUrl = 'applications/upload',
        activateOption = '?activate=true',
        iconUrlPrefix = 'rs/applications/',
        iconUrlSuffix = '/icon',
        dialogId = 'app-dialog',
        dialogOpts = {
            edge: 'right',
            width: 400
        },
        strongWarning = {
            'org.onosproject.drivers': true
        },
        discouragement = 'Deactivating or uninstalling this component can' +
        ' have serious negative consequences! <br> = DO SO AT YOUR OWN RISK =',
        propOrder = ['id', 'state', 'category', 'version', 'origin', 'role'],
        friendlyProps = ['App ID', 'State', 'Category', 'Version', 'Origin', 'Role'];
        // note: url is handled separately

    function createDetailsPane() {
        detailsPanel = ps.createPanel(pName, {
            width: wSize.width,
            margin: 0,
            hideMargin: 0
        });
        detailsPanel.el().style({
            position: 'absolute',
            top: pStartY + 'px'
        });
        $scope.hidePanel = function () { detailsPanel.hide(); };
        detailsPanel.hide();
    }

    function closePanel() {
        if (detailsPanel.isVisible()) {
            $scope.selId = null;
            detailsPanel.hide();
            return true;
        }
        return false;
    }

    function addCloseBtn(div) {
        is.loadEmbeddedIcon(div, 'close', 26);
        div.on('click', closePanel);
    }

    function setUpPanel() {
        var container, closeBtn, div;

        detailsPanel.empty();
        detailsPanel.width(panelWidth);

        container = detailsPanel.append('div').classed('container', true);

        top = container.append('div').classed('top', true);
        closeBtn = top.append('div').classed('close-btn', true);
        addCloseBtn(closeBtn);

        div = top.append('div').classed('top-content', true);

        function ndiv(cls, tcls) {
            var  d = div.append('div').classed(cls, true);
            if (tcls) {
                d.append('table').classed(tcls, true);
            }
        }

        ndiv('app-title');
        ndiv('left app-icon');
        ndiv('right', 'app-props');
        ndiv('app-url');

        container.append('hr');

        middle = container.append('div').classed('middle', true);
        middle.append('div').classed('app-readme', true);

        container.append('hr');

        // TODO: make bottom container scrollable
        bottom = container.append('div').classed('bottom', true);

        function nTable(hdr, cls) {
            bottom.append('h2').html(hdr);
            bottom.append('div').classed(cls, true).append('table');
        }

        nTable('Features', 'features');
        nTable('Required Apps', 'required-apps');
        nTable('Permissions', 'permissions');
    }

    function addProp(tbody, index, value) {
        var tr = tbody.append('tr');

        function addCell(cls, txt) {
            tr.append('td').attr('class', cls).html(txt);
        }

        addCell('label', friendlyProps[index] + ':');
        addCell('value', value);
    }

    function urlize(u) {
        return 'Url:<br/> <a href="' + u + '" target="_blank">' + u + '</a>';
    }

    function addIcon(elem, value) {
        elem.append('img').attr('src', iconUrlPrefix + value + iconUrlSuffix);
    }

    function populateTop(details) {
        var propsBody = top.select('.app-props').append('tbody'),
            url = details.url;

        top.select('.app-title').text(details.title);

        addIcon(top.select('.app-icon'), details.id);

        propOrder.forEach(function (prop, i) {
            addProp(propsBody, i, details[prop]);
        });

        if (url) {
            top.select('.app-url').html(urlize(url));
        }
    }

    function populateMiddle(details) {
        middle.select('.app-readme').text(details.readme);
    }

    function populateBottom(details) {

        function addItems(cls, items) {
            var table = bottom.select('.' + cls).select('table'),
                tbody = table.append('tbody');

            items.forEach(function (item) {
                tbody.append('tr').append('td').html(item);
            });
        }

        addItems('features', details.features);
        addItems('required-apps', details.required_apps);
        addItems('permissions', details.permissions);
    }

    function populateDetails(details) {
        setUpPanel();
        populateTop(details);
        populateMiddle(details);
        populateBottom(details);
        detailsPanel.height(pHeight);
    }

    function respDetailsCb(data) {
        $scope.panelData = data.details;
        $scope.selId = data.details.id;
        $scope.ctrlBtnState.selection = data.details.id;
        $scope.$apply();
    }

    angular.module('ovApp', [])
    .controller('OvAppCtrl',
        ['$log', '$scope', '$http', '$timeout',
         'WebSocketService', 'FnService', 'KeyService', 'PanelService',
         'IconService', 'UrlFnService', 'DialogService', 'TableBuilderService',

    function (_$log_, _$scope_, $http, $timeout, _wss_, _fs_, _ks_, _ps_, _is_,
              ufs, ds, tbs) {
        $log = _$log_;
        $scope = _$scope_;
        wss = _wss_;
        fs = _fs_;
        ks = _ks_;
        ps = _ps_;
        is = _is_;
        $scope.panelData = {};
        $scope.ctrlBtnState = {};
        $scope.uploadTip = 'Upload an application (.oar file)';
        $scope.activateTip = 'Activate selected application';
        $scope.deactivateTip = 'Deactivate selected application';
        $scope.uninstallTip = 'Uninstall selected application';

        var handlers = {};

        // details panel handlers
        handlers[detailsResp] = respDetailsCb;
        wss.bindHandlers(handlers);

        function selCb($event, row) {
            // $scope.selId is set by code in tableBuilder
            $scope.ctrlBtnState.selection = !!$scope.selId;
            refreshCtrls();
            ds.closeDialog();  // don't want dialog from previous selection

            if ($scope.selId) {
                wss.sendEvent(detailsReq, { id: row.id });
            } else {
                $scope.hidePanel();
            }
        }

        function refreshCtrls() {
            var row, rowIdx;
            if ($scope.ctrlBtnState.selection) {
                rowIdx = fs.find($scope.selId, $scope.tableData);
                row = rowIdx >= 0 ? $scope.tableData[rowIdx] : null;

                $scope.ctrlBtnState.installed = row && row.state === INSTALLED;
                $scope.ctrlBtnState.active = row && row.state === ACTIVE;
            } else {
                $scope.ctrlBtnState.installed = false;
                $scope.ctrlBtnState.active = false;
            }
        }

        tbs.buildTable({
            scope: $scope,
            tag: 'app',
            selCb: selCb,
            respCb: refreshCtrls,
            // pre-populate sort so active apps are at the top of the list
            sortParams: {
                firstCol: 'state',
                firstDir: 'desc',
                secondCol: 'title',
                secondDir: 'asc'
            }
        });

        // TODO: reexamine where keybindings should be - directive or controller?
        ks.keyBindings({
            esc: [$scope.selectCallback, 'Deselect application'],
            _helpFormat: ['esc']
        });
        ks.gestureNotes([
            ['click row', 'Select / deselect application'],
            ['scroll down', 'See more applications']
        ]);

        function createConfirmationText(action, itemId) {
            var content = ds.createDiv();
            content.append('p').text(fs.cap(action) + ' ' + itemId);
            if (strongWarning[itemId]) {
                content.append('p').html(discouragement).classed('strong', true);
            }
            return content;
        }

        function confirmAction(action) {
            var itemId = $scope.selId,
                spar = $scope.sortParams;

            function dOk() {
                $log.debug('Initiating', action, 'of', itemId);
                wss.sendEvent(appMgmtReq, {
                    action: action,
                    name: itemId,
                    sortCol: spar.sortCol,
                    sortDir: spar.sortDir
                });
                if (action == 'uninstall') {
                    detailsPanel.hide();
                } else {
                    wss.sendEvent(detailsReq, {id: itemId});
                }
            }

            function dCancel() {
                $log.debug('Canceling', action, 'of', itemId);
            }

            ds.openDialog(dialogId, dialogOpts)
                .setTitle('Confirm Action')
                .addContent(createConfirmationText(action, itemId))
                .addOk(dOk)
                .addCancel(dCancel)
                .bindKeys();
        }

        $scope.appAction = function (action) {
            if ($scope.ctrlBtnState.selection) {
                confirmAction(action);
            }
        };

        $scope.$on('FileChanged', function () {
            var formData = new FormData(),
                url;

            if ($scope.appFile) {
                formData.append('file', $scope.appFile);
                url = fileUploadUrl + activateImmediately;

                $http.post(ufs.rsUrl(url), formData, {
                    transformRequest: angular.identity,
                    headers: {
                        'Content-Type': undefined
                    }
                })
                .finally(function () {
                    activateImmediately = '';
                    $scope.sortCallback($scope.sortParams);
                    document.getElementById('inputFileForm').reset();
                    $timeout(function () { wss.sendEvent(detailsReq); }, 250);
                });
            }
        });

        $scope.appDropped = function() {
            activateImmediately = activateOption;
            $scope.$emit('FileChanged');
            $scope.appFile = null;
        };

        $scope.$on('$destroy', function () {
            ks.unbindKeys();
            wss.unbindHandlers(handlers);
            ds.closeDialog();
        });

        $log.log('OvAppCtrl has been created');
    }])

    // triggers the input form to appear when button is clicked
    .directive('triggerForm', function () {
        return {
            restrict: 'A',
            link: function (scope, elem) {
                elem.bind('click', function () {
                    document.getElementById('uploadFile')
                        .dispatchEvent(new MouseEvent('click'));
                });
            }
        };
    })

    // binds the model file to the scope in scope.appFile
    // sends upload request to the server
    .directive('fileModel', ['$parse',
        function ($parse) {
            return {
                restrict: 'A',
                link: function (scope, elem, attrs) {
                    var model = $parse(attrs.fileModel),
                        modelSetter = model.assign;

                    elem.bind('change', function () {
                        scope.$apply(function () {
                            modelSetter(scope, elem[0].files[0]);
                        });
                        scope.$emit('FileChanged');
                    });
                }
            };
        }])

    .directive("filedrop", function ($parse, $document) {
        return {
            restrict: "A",
            link: function (scope, element, attrs) {
                var onAppDrop = $parse(attrs.onFileDrop);

                // When an item is dragged over the document
                var onDragOver = function (e) {
                    d3.select('#frame').classed('dropping', true);
                    e.preventDefault();
                };

                // When the user leaves the window, cancels the drag or drops the item
                var onDragEnd = function (e) {
                    d3.select('#frame').classed('dropping', false);
                    e.preventDefault();
                };

                // When a file is dropped
                var loadFile = function (file) {
                    scope.appFile = file;
                    scope.$apply(onAppDrop(scope));
                };

                // Dragging begins on the document
                $document.bind("dragover", onDragOver);

                // Dragging ends on the overlay, which takes the whole window
                element.bind("dragleave", onDragEnd)
                    .bind("drop", function (e) {
                        $log.info('Drag leave', e);
                        loadFile(e.dataTransfer.files[0]);
                        onDragEnd(e);
                    });
            }
        };
    })

    .directive('applicationDetailsPanel',
        ['$rootScope', '$window', '$timeout', 'KeyService',
        function ($rootScope, $window, $timeout, ks) {
            return function (scope) {
                var unbindWatch;

                function heightCalc() {
                    pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
                                           + topPdg;
                    wSize = fs.windowSize(pStartY);
                    pHeight = wSize.height;
                }

                function initPanel() {
                    heightCalc();
                    createDetailsPane();
                    $log.debug('start to initialize panel!');
                }

                // Safari has a bug where it renders the fixed-layout table wrong
                // if you ask for the window's size too early
                if (scope.onos.browser === 'safari') {
                    $timeout(initPanel);
                } else {
                    initPanel();
                }
                // create key bindings to handle panel
                ks.keyBindings({
                    esc: [closePanel, 'Close the details panel'],
                    _helpFormat: ['esc']
                });
                ks.gestureNotes([
                    ['click', 'Select a row to show application details'],
                    ['scroll down', 'See more applications']
                ]);

                // if the panelData changes
                scope.$watch('panelData', function () {
                    if (!fs.isEmptyObject(scope.panelData)) {
                        populateDetails(scope.panelData);
                        detailsPanel.show();
                    }
                });

                // if the window size changes
                unbindWatch = $rootScope.$watchCollection(
                    function () {
                        return {
                            h: $window.innerHeight,
                            w: $window.innerWidth
                        };
                    }, function () {
                        if (!fs.isEmptyObject(scope.panelData)) {
                            heightCalc();
                            populateDetails(scope.panelData);
                        }
                    }
                );

                scope.$on('$destroy', function () {
                    unbindWatch();
                    ks.unbindKeys();
                    ps.destroyPanel(pName);
                });
            };
        }]);
}());
