/*
 * Copyright 2014-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.
 */

/*
 ONOS GUI -- Topology View Module
 */

(function () {
    'use strict';

    var moduleDependencies = [
        'ngCookies',
        'onosUtil',
        'onosSvg',
        'onosRemote',
    ];

    // references to injected services
    var $scope, $log, $loc, $timeout,
        fs, ks, zs, gs, ms, sus, flash, wss, ps, th, tds, t3s, tes, tfs, tps,
        tis, tms, tss, tls, tos, fltr, ttbs, tspr, tov;

    // DOM elements
    var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;

    // Internal state
    var zoomer,
        actionMap,
        topoLion = function (x) { return '#' + x + '#'; }; // func replaced later

    // --- Short Cut Keys ------------------------------------------------

    function setUpKeys(overlayKeys) {
        // key bindings need to be made after the services have been injected
        // thus, deferred to here...

        // we need functions that can be invoked after LION bundle loaded
        function togInst() { return topoLion('tbtt_tog_instances'); }
        function togSumm() { return topoLion('tbtt_tog_summary'); }
        function togUseDet() { return topoLion('tbtt_tog_use_detail'); }

        function togHost() { return topoLion('tbtt_tog_host'); }
        function togOff() { return topoLion('tbtt_tog_offline'); }
        function togPortHi() { return topoLion('tbtt_tog_porthi'); }

        function showBad() { return topoLion('tbtt_bad_links'); }
        function togMap() { return topoLion('tbtt_tog_map'); }
        function selMap() { return topoLion('tbtt_sel_map'); }
        function togSpr() { return topoLion('tbtt_tog_sprite'); }

        function rstLoc() { return topoLion('tbtt_reset_loc'); }
        function togOb() { return topoLion('tbtt_tog_oblique'); }
        function cycLayer() { return topoLion('tbtt_cyc_layers'); }
        function cycDev() { return topoLion('tbtt_cyc_dev_labs'); }
        function cycHost() { return topoLion('tbtt_cyc_host_labs'); }

        function unpin() { return topoLion('tbtt_unpin_node'); }
        function rzoom() { return topoLion('tbtt_reset_zoom'); }
        function togtb() { return topoLion('tbtt_tog_toolbar'); }
        function eqmaster() { return topoLion('tbtt_eq_master'); }

        function uiClick() { return topoLion('click'); }
        function uiShClick() { return topoLion('shift_click'); }
        function uiDrag() { return topoLion('drag'); }
        function uiCmdScr() { return topoLion('cmd_scroll'); }
        function uiCmdDrag() { return topoLion('cmd_drag'); }

        function uiClickTxt() { return topoLion('qh_gest_click'); }
        function uiShClickTxt() { return topoLion('qh_gest_shift_click'); }
        function uiDragTxt() { return topoLion('qh_gest_drag'); }
        function uiCmdScrTxt() { return topoLion('qh_gest_cmd_scroll'); }
        function uiCmdDragTxt() { return topoLion('qh_gest_cmd_drag'); }

        actionMap = {
            I: [toggleInstances, togInst],
            O: [toggleSummary, togSumm],
            D: [toggleUseDetailsFlag, togUseDet],

            H: [toggleHosts, togHost],
            M: [toggleOffline, togOff],
            P: [togglePorts, togPortHi],

            dash: [tfs.showBadLinks, showBad],
            B: [toggleMap, togMap],
            G: [openMapSelection, selMap],
            S: [toggleSprites, togSpr],

            X: [tfs.resetAllLocations, rstLoc],
            Z: [tos.toggleOblique, togOb],
            N: [fltr.clickAction, cycLayer],
            L: [tfs.cycleDeviceLabels, cycDev],
            'shift-L': [tfs.cycleHostLabels, cycHost],

            U: [tfs.unpin, unpin],
            R: [resetZoom, rzoom],
            dot: [ttbs.toggleToolbar, togtb],
            E: [equalizeMasters, eqmaster],

            // -- instance color palette debug
            // 9: function () { sus.cat7().testCard(svg); },

            // topology overlay selections
            F1: function () { ttbs.fnkey(0); },
            F2: function () { ttbs.fnkey(1); },
            F3: function () { ttbs.fnkey(2); },
            F4: function () { ttbs.fnkey(3); },
            F5: function () { ttbs.fnkey(4); },

            esc: handleEscape,

            _keyListener: ttbs.keyListener,

            _helpFormat: [
                ['I', 'O', 'D', 'H', 'M', 'P', 'dash', 'B', 'G', 'S'],
                ['X', 'Z', 'N', 'L', 'shift-L', 'U', 'R', '-', 'E', '-', 'dot'],
                [], // this column reserved for overlay actions
            ],
        };

        if (fs.isO(overlayKeys)) {
            mergeKeys(overlayKeys);
        }

        ks.keyBindings(actionMap);

        ks.gestureNotes([
            [uiClick, uiClickTxt],
            [uiShClick, uiShClickTxt],
            [uiDrag, uiDragTxt],
            [uiCmdScr, uiCmdScrTxt],
            [uiCmdDrag, uiCmdDragTxt],
        ]);
    }

    // when a topology overlay is activated, we need to bind their keystrokes
    // and include them in the quick-help panel
    function mergeKeys(extra) {
        var _hf = actionMap._helpFormat[2];

        ks.checkNotGlobal(extra);

        extra._keyOrder.forEach(function (k) {
            var d = extra[k],
                cb = d && d.cb,
                tt = d && d.tt;
            // NOTE: ignore keys that are already defined
            if (d && !actionMap[k]) {
                actionMap[k] = [cb, tt];
                _hf.push(k);
            }
        });
    }

    // --- Keystroke functions -------------------------------------------

    function toggleInstances(x) {
        updatePrefsState('insts', tis.toggle(x));
        tfs.updateDeviceColors();
    }

    function toggleSummary(x) {
        updatePrefsState('summary', tps.toggleSummary(x));
    }

    function toggleUseDetailsFlag(x) {
        updatePrefsState('detail', tps.toggleUseDetailsFlag(x));
    }

    function toggleHosts(x) {
        updatePrefsState('hosts', tfs.toggleHosts(x));
    }

    function toggleOffline(x) {
        updatePrefsState('offdev', tfs.toggleOffline(x));
    }

    function togglePorts(x) {
        updatePrefsState('porthl', tfs.togglePorts(x));
    }

    function _togSvgLayer(x, G, tag, what) {
        var on = (x === 'keyev') ? !sus.visible(G) : !!x,
            verb = on ? topoLion('show') : topoLion('hide');
        sus.visible(G, on);
        updatePrefsState(tag, on);
        flash.flash(verb + ' ' + what);
    }

    function toggleMap(x) {
        _togSvgLayer(x, mapG, 'bg', topoLion('fl_background_map'));
    }

    function openMapSelection() {
        tms.openMapSelection();
    }

    function toggleSprites(x) {
        _togSvgLayer(x, spriteG, 'spr', topoLion('fl_sprite_layer'));
    }

    function resetZoom() {
        zoomer.reset();
        flash.flash(topoLion('fl_pan_zoom_reset'));
    }

    function equalizeMasters() {
        wss.sendEvent('equalizeMasters');
        flash.flash(topoLion('fl_eq_masters'));
    }

    function handleEscape() {
        if (tis.showMaster()) {
            // if an instance is selected, cancel the affinity mapping
            tis.cancelAffinity();

        } else if (tov.hooks.escape()) {
            // else if the overlay consumed the ESC event...
            // (work already done)

        } else if (tss.deselectAll()) {
            // else if we have node selections, deselect them all
            // (work already done)

        } else if (tls.deselectAllLinks()) {
            // else if we have a link selected, deselect it
            // (work already done)

        } else if (tis.isVisible()) {
            // else if the Instance Panel is visible, hide it
            tis.hide();
            tfs.updateDeviceColors();

        } else if (tps.summaryVisible()) {
            // else if the Summary Panel is visible, hide it
            tps.hideSummary();
        }
    }

    // --- Toolbar Functions ---------------------------------------------

    function notValid(what) {
        $log.warn('topo.js getActionEntry(): Not a valid ' + what);
    }

    function getActionEntry(key) {
        var entry;

        if (!key) {
            notValid('key');
            return null;
        }

        entry = actionMap[key];

        if (!entry) {
            notValid('actionMap entry');
            return null;
        }
        return fs.isA(entry) || [entry, ''];
    }

    function setUpToolbar() {
        ttbs.init({
            getActionEntry: getActionEntry,
            setUpKeys: setUpKeys,
        });
        ttbs.createToolbar();
    }

    // --- Glyphs, Icons, and the like -----------------------------------

    function setUpDefs() {
        defs = svg.append('defs');
        gs.loadDefs(defs);
        sus.loadGlowDefs(defs);
    }


    // --- Pan and Zoom --------------------------------------------------

    // zoom enabled predicate. ev is a D3 source event.
    function zoomEnabled(ev) {
        return fs.isMobile() || (ev.metaKey || ev.altKey);
    }

    function zoomCallback() {
        var sc = zoomer.scale(),
            tr = zoomer.translate();

        ps.setPrefs('topo_zoom', { tx: tr[0], ty: tr[1], sc: sc });

        // keep the map lines constant width while zooming
        mapG.style('stroke-width', (2.0 / sc) + 'px');

        tfs.setNodeScale(sc);
    }

    function setUpZoom() {
        zoomLayer = svg.append('g').attr('id', 'topo-zoomlayer');
        zoomer = zs.createZoomer({
            svg: svg,
            zoomLayer: zoomLayer,
            zoomEnabled: zoomEnabled,
            zoomCallback: zoomCallback,
        });
    }


    // callback invoked when the SVG view has been resized..
    function svgResized(s) {
        tfs.newDim([s.width, s.height]);
    }

    // --- Background Map ------------------------------------------------

    function recenterLabel(g) {
        var box = g.node().getBBox();

        box.x -= box.width/2;
        box.y -= box.height/2;
        g.attr('transform', sus.translate(box.x, box.y));
    }

    function setUpNoDevs() {
        var g;

        noDevsLayer = svg.append('g').attr({
            id: 'topo-noDevsLayer',
            transform: sus.translate(500, 500),
        });
        // Note, SVG viewbox is '0 0 1000 1000', defined in topo.html.
        // We are translating this layer to have its origin at the center

        g = noDevsLayer.append('g');
        gs.addGlyph(g, 'bird', 100).attr('class', 'noDevsBird');
        g.append('text').text('').attr({x: 120, y: 80 });
        recenterLabel(g);
        showNoDevs(true);
    }

    function lionNoDevs() {
        var g = d3.select('#topo-noDevsLayer g');

        g.select('text').text(topoLion('no_devices_are_connected'));
        recenterLabel(g);
    }

    function showNoDevs(b) {
        sus.visible(noDevsLayer, b);
    }


    var countryFilters = {
        s_america: function (c) {
            return c.properties.continent === 'South America';
        },

        ns_america: function (c) {
            return c.properties.custom === 'US-cont' ||
                c.properties.subregion === 'Central America' ||
                c.properties.continent === 'South America';
        },

        japan: function (c) {
            return c.properties.geounit === 'Japan';
        },

        europe: function (c) {
            return c.properties.continent === 'Europe';
        },

        italy: function (c) {
            return c.properties.geounit === 'Italy';
        },

        uk: function (c) {
            // technically, Ireland is not part of the United Kingdom,
            // but the map looks weird without it showing.
            return c.properties.adm0_a3 === 'GBR' ||
                c.properties.adm0_a3 === 'IRL';
        },

        s_korea: function (c) {
            return c.properties.adm0_a3 === 'KOR';
        },

        australia: function (c) {
            return c.properties.adm0_a3 === 'AUS';
        },
    };

    var tintOn = 0,
        shadeFlip = 0,
        shadePalette = {
        light: {
            sea: 'aliceblue',
            land: 'white',
            outline: '#ddd',
        },
        dark: {
            sea: '#001830',
            land: '#232331',
            outline: '#3a3a3a',
        },
    };

    function shading() {
        return tintOn ? {
            palette: shadePalette[th.theme()],
            flip: shadeFlip,
        } : '';
    }

    function setMap(map) {
        ps.setPrefs('topo_mapid', map);
        setUpMap();
        opacifyMap(true);
    }

    function currentMap() {
        return ps.getPrefs(
            'topo_mapid',
            {
                mapid: 'usa',
                mapscale: 1,
                mapfilepath: '*continental_us',
                tint: 'off',
            },
            $loc.search()
        );
    }

    function setUpMap() {
        var prefs = currentMap(),
            mapId = prefs.mapid,
            mapFilePath = prefs.mapfilepath,
            mapScale = prefs.mapscale,
            tint = prefs.tint,
            promise,
            cfilter;

        tintOn = tint === 'on' ? 1 : 0;

        $log.debug('setUpMap() mapId:', mapId, ', mapScale:', mapScale,
                   ', tint:', tint);

        mapG = d3.select('#topo-map');
        if (mapG.empty()) {
            mapG = zoomLayer.append('g').attr('id', 'topo-map');
        } else {
            mapG.each(function (d, i) {
                d3.selectAll(this.childNodes).remove();
            });
        }

        if (mapFilePath === '*countries') {

            cfilter = countryFilters[mapId] || countryFilters.uk;

            promise = ms.loadMapRegionInto(mapG, {
                countryFilter: cfilter,
                adjustScale: mapScale,
                shading: shading(),
            });
        } else {

            promise = ms.loadMapInto(mapG, mapFilePath, mapId, {
                adjustScale: mapScale,
                shading: shading(),
            });
        }

        ps.setPrefs('topo_mapid', prefs);
        return promise;
    }

    function mapReshader() {
        $log.debug('... Re-shading map ...');
        ms.reshade(shading());
    }

    // set up theme listener to re-shade the map when required.
    function mapShader(on) {
        if (on) {
            th.addListener(mapReshader);
        } else {
            th.removeListener(mapReshader);
        }
    }

    function opacifyMap(b) {
        mapG.transition()
            .duration(1000)
            .attr('opacity', b ? 1 : 0);
    }

    function setUpSprites() {
        var prefs = ps.getPrefs('topo_sprites', { sprites: '' }, $loc.search()),
            sprId = prefs.sprites;

        spriteG = zoomLayer.append('g').attr('id', 'topo-sprites');
        if (sprId) {
            ps.setPrefs('topo_sprites', prefs);
            tspr.loadSprites(spriteG, defs, sprId);
        }
    }

    // --- User Preferemces ----------------------------------------------

    var prefsState = {};

    function updatePrefsState(what, b) {
        prefsState[what] = b ? 1 : 0;
        ps.setPrefs('topo_prefs', prefsState);
    }


    function restoreConfigFromPrefs() {
        // NOTE: toolbar will have set this for us..
        prefsState = ps.asNumbers(
            ps.getPrefs('topo_prefs', ttbs.defaultPrefs), ['ovid'], true
        );

        $log.debug('TOPO- Prefs State:', prefsState);

        flash.enable(false);
        toggleInstances(prefsState.insts);
        toggleSummary(prefsState.summary);
        toggleUseDetailsFlag(prefsState.detail);
        toggleHosts(prefsState.hosts);
        toggleOffline(prefsState.offdev);
        togglePorts(prefsState.porthl);
        toggleMap(prefsState.bg);
        toggleSprites(prefsState.spr);
        t3s.setDevLabIndex(prefsState.dlbls);
        t3s.setHostLabIndex(prefsState.hlbls);
        flash.enable(true);
    }


    // somewhat hackish, because summary update cannot happen until we
    //  have opened the websocket to the server; hence this extra function
    // invoked after tes.start()
    function restoreSummaryFromPrefs() {
        prefsState = ps.asNumbers(
            ps.getPrefs('topo_prefs', ttbs.defaultPrefs), ['ovid'], true
        );
        $log.debug('TOPO- Prefs SUMMARY State:', prefsState.summary);

        flash.enable(false);
        toggleSummary(prefsState.summary);
        flash.enable(true);
    }

    // initial set of topo events received, now do post-processing
    function topoStartDone() {
        // give a small delay before attempting to reselect node(s) and
        // highlight elements, since they have to be re-added to the DOM first...
        $timeout(function () {
            $log.debug('^^ topo.topoStartDone() ^^');

            // reselect the previous selection...
            tss.reselect();

            // if an intent should be shown, invoke the appropriate callback
            if ($scope.intentData) {
                tov.hooks.showIntent($scope.intentData);
            }

        }, 200);
    }

    // --- Controller Definition -----------------------------------------

    angular.module('ovTopo', moduleDependencies)
        .controller('OvTopoCtrl',
            ['$scope', '$log', '$location', '$timeout', '$cookies',
            'FnService', 'MastService', 'KeyService', 'ZoomService',
            'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
            'WebSocketService', 'PrefsService', 'ThemeService',
            'TopoDialogService', 'TopoD3Service', 'TopoEventService',
            'TopoForceService', 'TopoPanelService', 'TopoInstService',
            'TopoSelectService', 'TopoLinkService', 'TopoTrafficService',
            'TopoObliqueService', 'TopoFilterService', 'TopoToolbarService',
            'TopoMapService', 'TopoSpriteService', 'TooltipService',
            'TopoOverlayService', 'LionService',

                function (_$scope_, _$log_, _$loc_, _$timeout_, _$cookies_,
                  _fs_, mast, _ks_, _zs_,
                  _gs_, _ms_, _sus_, _flash_,
                  _wss_, _ps_, _th_,
                  _tds_, _t3s_, _tes_,
                  _tfs_, _tps_, _tis_,
                  _tss_, _tls_, _tts_,
                  _tos_, _fltr_, _ttbs_,
                  _tms_, _tspr_, _ttip_,
                  _tov_, lion) {

            var params = _$loc_.search(),
                selOverlay = params.overlayId,
                projection,
                dim,
                uplink = {
                    // provides function calls back into this space
                    showNoDevs: showNoDevs,
                    projection: function () { return projection; },
                    zoomLayer: function () { return zoomLayer; },
                    zoomer: function () { return zoomer; },
                    opacifyMap: opacifyMap,
                    topoStartDone: topoStartDone,
                };

            $scope = _$scope_;
            $log = _$log_;
            $loc = _$loc_;
            $timeout = _$timeout_;
            fs = _fs_;
            ks = _ks_;
            zs = _zs_;
            gs = _gs_;
            ms = _ms_;
            sus = _sus_;
            flash = _flash_;
            wss = _wss_;
            ps = _ps_;
            th = _th_;
            tds = _tds_;
            t3s = _t3s_;
            tes = _tes_;
            tfs = _tfs_;
            // TODO: consider funnelling actions through TopoForceService...
            //  rather than injecting references to these 'sub-modules',
            //  just so we can invoke functions on them.
            tps = _tps_;
            tis = _tis_;
            tms = _tms_;
            tls = _tls_;
            tos = _tos_;
            fltr = _fltr_;
            ttbs = _ttbs_;
            tspr = _tspr_;
            tov = _tov_;
            tss = _tss_;

            tms.start({
                toggleMap: toggleMap,
                currentMap: currentMap,
                setMap: setMap,
            });

            // pull intent data from the query string...
            if (params.key && params.appId && params.appName) {
                $scope.intentData = {
                    key: params.key,
                    appId: params.appId,
                    appName: params.appName,
                    intentType: params.intentType,
                };
            }

            $scope.notifyResize = function () {
                svgResized(fs.windowSize(mast.mastHeight()));
            };

            // Cleanup on destroyed scope..
            $scope.$on('$destroy', function () {
                $log.log('OvTopoCtrl is saying Buh-Bye!');
                tes.stop();
                tms.stop();
                ks.unbindKeys();
                tps.destroyPanels();
                tds.closeDialog();
                tis.destroyInst();
                tfs.destroyForce();
                ttbs.destroyToolbar();
                mapShader(false);
            });

            // svg layer and initialization of components
            ovtopo = d3.select('#ov-topo');
            svg = ovtopo.select('svg');
            // set the svg size to match that of the window, less the masthead
            svg.attr(fs.windowSize(mast.mastHeight()));
            dim = [svg.attr('width'), svg.attr('height')];

            setUpKeys();
            setUpToolbar();
            setUpDefs();
            setUpZoom();
            setUpNoDevs();
            setUpMap().then(
                function (proj) {
                    var z = ps.getPrefs('topo_zoom', { tx: 0, ty: 0, sc: 1 });
                    zoomer.panZoom([z.tx, z.ty], z.sc);
                    $log.debug('** Zoom restored:', z);

                    projection = proj;
                    $log.debug('** We installed the projection:', proj);
                    flash.enable(false);
                    toggleMap(prefsState.bg);
                    flash.enable(true);
                    mapShader(true);

                    // piggyback off the deferred map loading to load the
                    // localization bundle after the uber bundle has arrived...
                    $scope.lion = lion.bundle('core.view.Topo');
                    topoLion = $scope.lion;
                    $log.debug('Loaded Topo LION Bundle:', topoLion);

                    // insert localized text into already established
                    // DOM elements...
                    lionNoDevs();

                    // pass lion bundle function ref to other topo modules
                    tfs.setLionBundle(topoLion);
                    tis.setLionBundle(topoLion);
                    tms.setLionBundle(topoLion);
                    tps.setLionBundle(topoLion);

                    // now we have the map projection, we are ready for
                    //  the server to send us device/host data...
                    tes.start();
                    // need to do the following so we immediately get
                    //  the summary panel data back from the server
                    restoreSummaryFromPrefs();
                }
            );
            tes.bindHandlers();
            setUpSprites();

            forceG = zoomLayer.append('g').attr('id', 'topo-force');
            tfs.initForce(svg, forceG, uplink, dim);
            tis.initInst({ showMastership: tfs.showMastership });
            tps.initPanels();

            restoreConfigFromPrefs();

            ttbs.selectOverlay(selOverlay || prefsState.ovid);

            $log.debug('registered overlays...', tov.list());
            $log.log('OvTopoCtrl has been created');
        }]);
}());
