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

/*PCE topology overlay web application implementation.*/

(function () {
    'use strict';

    // injected refs
    var $log, fs, flash, wss, tps, ns, tds, ds;
    var tunnelNameData, tunnelNameDataRemove, tunnelDataUpdateInfo, tunnelIdUpd;
   // constants
    var srcMessage = 'pceTopovSetSrc',
        dstMessage = 'pceTopovSetDst',
        clearMessage = 'pceTopovClear',
        setPathmsg =  'pceTopovSetMode',
        updatePathmsgQuery = 'pceTopovUpdateQuery',
        remPathmsgQuery = 'pceTopovRemQuery',
        updatePathmsg = 'pceTopovUpdate',
        updatePathmsgInfo = 'updatePathmsgInfo',
        remPathmsg = 'pceTopovRem',
        showTunnelInfoMsg = 'pceTopovShowTunnels',
        queryDisplayTunnelMsg = 'pceTopovTunnelDisplay',
        showTunnelInfoRemoveMsg = 'pceTopovShowTunnelsRem',
        showTunnelInfoUpdateMsg = 'pceTopovShowTunnelsUpdate';
    // internal state
    var currentMode = null;
    var handlerMap = {},
        handlerMapRem = {},
        handlerMapShowUpdate = {};
    // === ---------------------------
    // === Helper functions

    // === ---------------------------
    // === Main API functions

    function setSrc(node) {
        wss.sendEvent(srcMessage, {
            id: node.id,
            type: node.type
        });
        flash.flash('Source node: ' + node.id);
    }

    function setDst(node) {
        wss.sendEvent(dstMessage, {
            id: node.id,
            type: node.type
        });
        flash.flash('Destination node: ' + node.id);
    }

    function clear() {
        wss.sendEvent(clearMessage);
        flash.flash('Cleared source and destination');
    }

    function dClose() {
        $log.debug('Dialog Close button clicked (or Esc pressed)');
    }

    function createUserText() {
        var content = ds.createDiv('constraints-input'),
            form = content.append('form'),
            p = form.append('p');

        function addAttribute(name, id, nameField, type) {
            if (type == 'radio') {
                p.append('input').attr({
                    type: type,
                    name: name,
                    id: id,
                    class: 'radioButtonSpace'
                });
            } else {
                p.append('input').attr({
                    type: type,
                    name: name,
                    id: id
                });
            }
            p.append('span').text(nameField);
            p.append('br');
        }

        //Add the bandwidth related inputs.
        addAttribute('band-width-name', 'band-width-box', 'Band Width', 'checkbox');
        addAttribute('band-width-value-name', 'band-width-value', null, 'number');
        addAttribute('pce-band-type', 'band-kpbs-val', 'kbps', 'radio');
        addAttribute('pce-band-type', 'band-mpbs-val', 'mbps', 'radio');
        addAttribute('pce-band-type', 'band-bps-val', 'bps', 'radio');
        //Add the cost type related inputs.
        addAttribute('pce-cost-type-name', 'pce-cost-type', 'Cost Type', 'checkbox');
        addAttribute('pce-cost-type-valname', 'pce-cost-type-igp', 'IGP', 'radio');
        addAttribute('pce-cost-type-valname', 'pce-cost-type-te', 'TE', 'radio');
        //Add the LSP type related inputs.
        addAttribute('pce-lsp-type-name', 'pce-lsp-type', 'Lsp Type', 'checkbox');
        addAttribute('pce-lsp-type-valname', 'pce-lsp-type-cr', 'With signalling', 'radio');
        addAttribute('pce-lsp-type-valname', 'pce-lsp-type-srbe', 'Without SR without signalling', 'radio');
        addAttribute('pce-lsp-type-valname', 'pce-lsp-type-srte', 'With SR without signalling', 'radio');
        //Add the tunnel name
        addAttribute('pce-tunnel-name', 'pce-tunnel-name-id', 'Tunnel Name', 'text');

        return content;
    }

    function createUserTextUpdate(data) {
        var content = ds.createDiv(),
            form = content.append('form'),
            p = form.append('p');

        p.append('span').text('Tunnel IDs');
        p.append('br');

        data.a.forEach( function (val, idx) {
            p.append('input').attr({
                id: 'tunnel-id-'+idx,
                type: 'radio',
                name: 'tunnel-id-name',
                value: val
            });

            p.append('span').text(val);
            p.append('br');

        } );

        return content;
    }

    function createUserTextUpdatePathEvent(data) {
        var content = ds.createDiv(),
            form = content.append('form'),
            p = form.append('p');
        var constType;

        function addAttribute(name, id, nameField, type) {
            if (type == 'radio') {
                p.append('input').attr({
                    type: type,
                    name: name,
                    id: id,
                    class: 'radioButtonSpace'
                });
            }
            else {
                p.append('input').attr({
                    type: type,
                    name: name,
                    id: id
                });
            }

            p.append('span').text(nameField);
            p.append('br');
        }

        data.a.forEach( function (val, idx) {
            if (val == 'Tunnel') {
                constType = 'TUNNEL';
                return;
            }

            if (val == 'BandWidth') {
                constType = 'BW';
                return;
            }

            if (val == 'CostType') {
                constType = 'CT';
                return;
            }

            if (constType == 'TUNNEL') {
                p.append('span').text('Tunnel Id: ');
                p.append('span').text(val);
                p.append('br');
                tunnelIdUpd = val;
            }

            if (constType == 'BW') {
                addAttribute('band-width-name', 'update-band-width-box', 'Band Width', 'checkbox');
                p.append('input').attr({
                    id: 'update-band-width-value',
                    type: 'number',
                    name: 'band-width-value-name',
                    value: val
                });
                p.append('br');
                p.append('input').attr({
                    id: 'update-band-bps-val',
                    type: 'radio',
                    name: 'pce-band-type',
                    checked: 'checked',
                    class: 'radioButtonSpace'
                });
                p.append('span').text('bps');
                p.append('br');
                addAttribute('pce-band-type', 'update-band-kbps-val', 'kbps', 'radio');
                addAttribute('pce-band-type', 'update-band-mbps-val', 'mbps', 'radio');
            }

            if (constType == 'CT') {
                addAttribute('pce-cost-type', 'update-pce-cost-type', 'Cost Type', 'checkbox');
                if (val == 'COST') {
                    p.append('input').attr({
                        id: 'update-pce-cost-type-igp',
                        type: 'radio',
                        name: 'pce-cost-type-value',
                        checked: 'checked',
                        class: 'radioButtonSpace'
                    });
                    p.append('span').text('IGP');
                    p.append('br');
                    addAttribute('pce-cost-type-value', 'update-pce-cost-type-te', 'TE', 'radio');
 
                } else {
                    addAttribute('pce-cost-type-value', 'update-pce-cost-type-igp', 'IGP', 'radio');
                    p.append('input').attr({
                        id: 'update-pce-cost-type-te',
                        type: 'radio',
                        name: 'pce-cost-type-value',
                        checked: 'checked',
                        class: 'radioButtonSpace'
                    });
                    p.append('span').text('TE');
                    p.append('br');
                }
            }
        } );

        return content;
    }

    function createUserTextRemove(data) {

        var content = ds.createDiv(),
            form = content.append('form'),
            p = form.append('p');

        p.append('span').text('Tunnel IDs');
        p.append('br');

        data.a.forEach( function (val, idx) {
            p.append('input').attr({
                id: 'tunnel-id-remove-'+idx,
                type: 'checkbox',
                name: 'tunnel-id-name-remove',
                value: val
            });

            p.append('span').text(val);
            p.append('br');
        } );

        return content;
    }

    function isChecked(cboxId) {
        return d3.select('#' + cboxId).property('checked');
    }

    function getCheckedValue(cboxId) {
        return d3.select('#' + cboxId).property('value');
    }

    function showTunnelInformation(data) {
        wss.unbindHandlers(handlerMap);
        tunnelNameData = data;

        function dOkUpdate() {
            var tdString = '' ;
            tunnelNameData.a.forEach( function (val, idx) {
                var tunnelName = isChecked('tunnel-id-'+idx);
                if (tunnelName) {
                    tdString = val;
                }
            } );
            //send event to server for getting the tunnel information.
            if (tdString != null) {
                handlerMapShowUpdate[showTunnelInfoUpdateMsg] = showTunnelInfoUpdateMsgHandle;
                wss.bindHandlers(handlerMapShowUpdate);

                wss.sendEvent(updatePathmsgInfo, {
                    tunnelid: tdString
                });
            }
            //constraintsUpdateDialog(tdString);
            $log.debug('Dialog OK button clicked');
        }

        tds.openDialog()
            .setTitle('Available LSPs with selected device')
            .addContent(createUserTextUpdate(data))
            .addOk(dOkUpdate, 'OK')
            .addCancel(dClose, 'Close')
            .bindKeys();
    }

    function dOkUpdateEvent() {
        $log.debug('Select constraints for update path Dialog OK button pressed');

        var bandWidth = isChecked('update-band-width-box'),
            bandValue = null,
            bandType = null;

        if (bandWidth) {
            bandValue = getCheckedValue('update-band-width-value');

            if (isChecked('update-band-kbps-val')) {
                    bandType = 'kbps';
            } else if (isChecked('update-band-mbps-val')) {
                    bandType = 'mbps';
            } else if (isChecked('update-band-bps-val')) {
                    bandType = 'bps';
            }
        }

        var costType = isChecked('update-pce-cost-type'),
            costTypeVal = null;

        if (costType) {
            if (isChecked('update-pce-cost-type-igp')) {
                costTypeVal = 'igp';
            } else if (isChecked('update-pce-cost-type-te')) {
                costTypeVal = 'te';
            }
        }

        wss.sendEvent(updatePathmsg, {
                bw: bandValue,
                bwtype: bandType,
                ctype: costTypeVal,
                tunnelname: tunnelIdUpd
        });

        flash.flash('update path message');

    }

    function showTunnelInformationRemove(data) {

        wss.unbindHandlers(handlerMapRem);
        tunnelNameDataRemove = data;
        tds.openDialog()
            .setTitle('Available Tunnels for remove')
            .addContent(createUserTextRemove(data))
            .addOk(dOkRemove, 'OK')
            .addCancel(dClose, 'Close')
            .bindKeys();
    }

    function showTunnelInfoUpdateMsgHandle(data) {

        wss.unbindHandlers(handlerMapShowUpdate);
        tunnelDataUpdateInfo = data;
        tds.openDialog()
            .setTitle('Constrainst selection for update')
            .addContent(createUserTextUpdatePathEvent(data))
            .addOk(dOkUpdateEvent, 'OK')
            .addCancel(dClose, 'Close')
            .bindKeys();
    }

    //setup path
    function setMode(node) {

        function dOk() {
            var bandWidth = isChecked('band-width-box'),
                bandValue = null,
                bandType = null;

            if (bandWidth) {
                bandValue = getCheckedValue('band-width-value');

                if (isChecked('band-kpbs-val')) {
                    bandType = 'kbps';
                } else if (isChecked('band-mpbs-val')) {
                    bandType = 'mbps';
                } else if (isChecked('band-bps-val')) {
                    bandType = 'bps';
                }
            }

            var costType = isChecked('pce-cost-type'),
                costTypeVal = null;

            if (costType) {
                if (isChecked('pce-cost-type-igp')) {
                    costTypeVal = 'igp';
                } else if (isChecked('pce-cost-type-te')) {
                   costTypeVal = 'te';
                }
            }

            var lspType = isChecked('pce-lsp-type'),
                lspTypeVal = null;

            if (lspType) {
                if (isChecked('pce-lsp-type-cr')) {
                   lspTypeVal = 'cr';
                } else if (isChecked('pce-lsp-type-srbe')) {
                   lspTypeVal = 'srbe';
                } else if (isChecked('pce-lsp-type-srte')) {
                   lspTypeVal = 'srte';
                }
            }

            wss.sendEvent(setPathmsg, {
                srid: node[0],
                dsid: node[1],
                bw: bandValue,
                bwtype: bandType,
                ctype: costTypeVal,
                lsptype: lspTypeVal,
                tunnelname: getCheckedValue('pce-tunnel-name-id')
            });

            flash.flash('create path message');
            $log.debug('Dialog OK button clicked');
        }

        tds.openDialog()
        .setTitle('constraints selection')
        .addContent(createUserText())
        .addOk(dOk, 'OK')
        .addCancel(dClose, 'Close')
        .bindKeys();
    }

    function updatePath(node) {

        wss.sendEvent(updatePathmsgQuery, {
            srid: node[0],
            dsid: node[1]
        });

        handlerMap[showTunnelInfoMsg] = showTunnelInformation;
        wss.bindHandlers(handlerMap);

        flash.flash('update path message');
    }

    function dOkRemove() {

        tunnelNameDataRemove.a.forEach( function (val, idx) {
            var tunnelNameVal = isChecked('tunnel-id-remove-'+idx);
            if (tunnelNameVal) {
                wss.sendEvent(remPathmsg, {
                    tunnelid: val
                });
            }
        } );

        flash.flash('remove path message');
    }

    function remPath(node) {
        wss.sendEvent(remPathmsgQuery, {
            srid: node[0],
            dsid: node[1]
        });

        handlerMapRem[showTunnelInfoRemoveMsg] = showTunnelInformationRemove;
        wss.bindHandlers(handlerMapRem);
    }

  function queryTunnelDisplay() {
        wss.sendEvent(queryDisplayTunnelMsg);
    }
    // === ---------------------------
    // === Module Factory Definition

    angular.module('ovPcewebTopov', [])
        .factory('PcewebTopovDemoService',
        ['$log', 'FnService', 'FlashService', 'WebSocketService',
        'TopoPanelService', 'NavService', 'TopoDialogService', 'DialogService',

        function (_$log_, _fs_, _flash_, _wss_, _tps_, _ns_,_tds_, _ds_) {
            $log = _$log_;
            fs = _fs_;
            flash = _flash_;
            wss = _wss_;
            tps = _tps_;
            ns = _ns_;
            tds = _tds_;
            ds = _ds_;

            return {
                setSrc: setSrc,
                setDst: setDst,
                clear: clear,
                setMode: setMode,
                updatePath: updatePath,
                remPath: remPath,
                queryTunnelDisplay: queryTunnelDisplay
            };
        }]);
}());
