{% extends "admin/base.html" %}
{% load admin_static %}

{% block content %}
<link rel="stylesheet"  href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="{% static 'suit/css/suit.css' %}" media="all">
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables_themeroller.css">
<link rel="stylesheet" type="text/css" href="{% static 'planetstack.css' %}" media="all">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>


<!-- no need to include jquery here as it's already included by base.html. Including it multiple times will break mtuity statistics. -->
<!-- src="http://code.jquery.com/jquery-1.9.1.js" -->

<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="{% static 'log4javascript-1.4.6/log4javascript.js' %}"></script>
<script src="{% static 'js/Leaflet.MakiMarkers.js' %}" > </script>
  
<script>
  $(function() {
    $( "#hometabs" ).tabs({active: 0, //event: "mouseover"
      //collapsible: true
    });
  });
</script>
<script>

function confirmDialog(title,msg) {
    var dialog = $('<div>'+msg+'</div>');
    var def = $.Deferred();

    $(dialog).dialog({
        resizable: false,
        title: title,
        autoOpen: true,
        modal: true,
        dialogClass: "dashboard-hpc-sliver",
        buttons: {
            'OK': function() {
                def.resolve();
                log.debug("Chose to add a sliver");
                $( this ).dialog( "close" );
            },
            'Cancel': function() {
                def.reject();
                $( this ).dialog( "close" );
            }
        },
        close: {
        }
    });
    return def.promise();
}

  </script>

<!-- <div id="hometabs" class="inner-center-column ui-tabs ui-widget ui-widget-content ui-corner-all"> -->
<div id="hometabs" >
  <ul id="suit_form_tabs" class="nav nav-tabs nav-tabs-suit" data-tab-prefix="suit-tab">
    <li><a href="#tabs-1">Developer View</a></li>
    <li><a href="#tabs-2">CDN Operations </a></li>
    <li><a href="#tabs-3">Historical</a></li>
    <li><a href="#tabs-4">Slice Interactions</a></li>
    <li><a href="#tabs-5">Tenant</a></li>
  </ul>
<div id="tabs-1">
</div>
<div id="tabs-2">
    <div id="HPCDashboard">
    <h1>CDN Operations View</h1>
    <span id="hpcSummary">
        <span class="summary-attr"><b>Active Slivers:</b> <span id="active-slivers-value"> </span> </span>
        <span class="summary-attr"><b>Overall Throughput:</b> <span id="overall-throughput-value"> </span>  </span>
        <span class="summary-attr-util"><b>Average CPU Utilization:</b> <span id="cpu-utilization-value"> </span>  </span>
    </span>
    <div id="map-us" ></div>
    <div style="line-height: 30%"><br></div><table border=0><tr>
    <td>Least Loaded&nbsp;&nbsp;</td>
    <td bgcolor="#0000FF" width=40>&nbsp;</td>
    <td bgcolor="#00FFFF" width=40>&nbsp;</td>
    <td bgcolor="#00FF00" width=40>&nbsp;</td>
    <td bgcolor="#FFFF00" width=40>&nbsp;</td>
    <td bgcolor="#FF0000" width=40>&nbsp;</td>
    <td>&nbsp;&nbsp;Most Loaded</td>
    </tr></table>
    </div>
</div>
<div id="tabs-3">
{% include "/opt/planetstack/templates/admin/dashboard/hpc_historical.html" %}
</div>
<div id="tabs-4">
{% include "/opt/planetstack/templates/admin/dashboard/slice_interactions.html" %}
</div>
<div id="tabs-5">
Coming Soon ...
</div>
</div>

<div id="confirmNodeAdded" title="Added Node to Site"><p>Added Node to Site</p></div>
<div id="confirmNodeRemoved" title="Removed Node from Site"><p>Added Node to Site</p></div>
<script>
var oTable;
var consoleAppender = new log4javascript.BrowserConsoleAppender();
var patternLayout = new log4javascript.PatternLayout("%d{HH:mm:ss,SSS} %l{s:l} %-5p - %m{1}%n");
consoleAppender.setLayout(patternLayout);

//var log  = log4javascript.getDefaultLogger();
var log  = log4javascript.getRootLogger();
log.addAppender(consoleAppender);
log.setLevel(log4javascript.Level.ERROR);

function updateUserSliceTable(){
    log.debug("Should grab user slice info");
    jQuery.ajax({
        async:true,
        dataType: 'json',
        url: '/hpcdashuserslices',
        success: function(data){
            log.info("Got Data back for User SliceTable");
            //parseData(data);
            //createUserSliceTable(data);
            setTimeout(function () { updateUserSliceTable() }, 5000);
        },
        error: function(data){
            log.debug("COULDNT GET DATA BACK");
            setTimeout(function () { updateUserSliceTable() }, 5000);
        }
    });
}

function createUserSliceTable(data) {
    log.debug("Creating User Slice Table");

    //Add check for #dynamicusersliceinfo_filter label-> input having focus here

    $('#tabs-1').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="dynamicusersliceinfo"></table>' );
    var actualEntries = [];
    log.debug(data['userSliceInfo']['rows'][0]['slicename']);

    var rows = data['userSliceInfo']['rows'];
    for (row in rows) {
        log.debug(row[0]);
        slicename = rows[row]['slicename'];
        sliceid = rows[row]['sliceid'];
        role = rows[row]['role'];
        slivercount = rows[row]['slivercount'];
        sitecount = rows[row]['sitecount'];
        actualEntries.push(['<a href="http://{{request.get_host}}/admin/core/slice/' + sliceid + '">' + slicename + '</a>',
                            role, slivercount, sitecount]);
    }
    oTable = $('#dynamicusersliceinfo').dataTable( {
        "bJQueryUI": true,
        "aaData":  actualEntries ,
        "bStateSave": true,
        "aoColumns": [
            { "sTitle": "Slice" },
            { "sTitle": "Privilege" , sClass: "alignCenter"},
            { "sTitle": "Number of Slivers" , sClass: "alignCenter"},
            { "sTitle": "Number of Sites" , sClass: "alignCenter"},
        ]
    } );

    // If the filter had focus, reapply here

    setTimeout(function() {
       jQuery.ajax({
           url: '/hpcdashuserslices',
           dataType: 'json',
           success: function(data){ createUserSliceTable(data); },
           complete: function(){ },
       });
    },  10000);
}

function initTable(){
    log.debug("Initializing Table")
    jQuery.ajax({
        url: '/hpcdashuserslices',
        dataType: 'json',
        success: function(data){ createUserSliceTable(data); },
        complete: function(){
        }
    });
    updateUserSliceTable();
}


initTable();

$( "#confirmNodeAdded" ).dialog({ autoOpen: false,
                    modal: true,
                    buttons: {
                        Ok: function() {
                           $( this ).dialog( "close" );
                        }
                    }});
$( "#confirmNodeRemoved" ).dialog({ autoOpen: false });

L.Map = L.Map.extend({
    openPopup: function(popup) {
        this._popup = popup;

        return this.addLayer(popup).fire('popupopen', {
            popup: this._popup
        });
    }
});


//Iterate through data and find the max/min coordinates to include all of our points to start
var map = L.map('map-us'); //.setView([0, 0], 1);
map.scrollWheelZoom.disable();

//
// Great tiles, but starting to occasionally see 403 errors on certain tiles causing grey out effect
//L.tileLayer('http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png', {
//
// Swapping out cloudmade tiles to openstreetmap - too many grey tiles showing
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: 'Test'
}).addTo(map);

var arrayOfLatLngs = [];
var mapData = {{ cdnData|safe }};
log.debug( mapData );

for ( var key in mapData ) {
    arrayOfLatLngs.push([mapData[key]['lat'],mapData[key]['long']]);
    log.debug( arrayOfLatLngs );

    mapData[key]['marker'] = L.marker([mapData[key]['lat'], mapData[key]['long']], {icon: getIcon(mapData[key]['numNodes'], mapData[key]['numHPCSlivers'], 0, mapData[key]['hot']) });
    mapData[key]['marker'].addTo(map).bindPopup(setPopupVals(key, mapData[key]));

}
var bounds = new L.LatLngBounds(arrayOfLatLngs);
map.fitBounds(bounds);

var popup = L.popup();


function setPopupVals (site, siteData) {
    var retVal = '<span class="SiteDetail"><b>' + site + '</b></span>' + 
                   '</br><a href="' + siteData['siteUrl'] + '">' + siteData['siteUrl'] + '</a>' + 
                   '</br><b>HPC Slivers: </b>' + siteData['numHPCSlivers'] + 
                   '</br><b>Total Nodes: </b>' + siteData['numNodes'] +
//                   '</br><b>Hot: </b>' + Math.round(siteData['hot']*100) +
                   '</br><b>Measured Load: </b>' + siteData['load'] + '%' +
                   '<span id="addSlivers"></br><a href="#" id="addHPCSliver" data-site="' + site + '" data-availNodes="' + siteData['numNodes'] +'">Add HPC Slivers</a> </span>' +
                   '<span id="remSlivers"><a href="#" id="remHPCSliver" data-site="' + site + '">Remove HPC Slivers</a> </span>';

   return retVal;
}

$('#map-us').on('click', '#remHPCSliver', function() {
   
    $.ajax({
        url : '/dashboardaddorremsliver/',
        dataType : 'json',
        data: {site: $(this).data('site'),
               actionToDo: "rem",
               csrfmiddlewaretoken: "{{ csrf_token }}",   // < here 
               state:"inactive" },
        type : 'POST',
        //success: function(response)
        //{
         //   alert("Successfully posted request to REMOVE sliver");
        //},
        complete:function(){
            confirmDialog("Info","Removed an HPC Sliver from Site ");
        },
        //error:function (xhr, textStatus, thrownError){
         //   alert("Could not request to remove HPC Sliver");
        //}
    });
});

$('#map-us').on('click', '#addHPCSliver', function() {
   
    $.ajax({
        url : '/dashboardaddorremsliver/',
        dataType : 'json',
        data: {site: $(this).data('site'),
               actionToDo: "add",
               csrfmiddlewaretoken: "{{ csrf_token }}",   // < here 
               state:"inactive" },
        type : 'POST',
        success: function(response)
        {
            //alert("Successfully posted request to add sliver");
        },
        complete:function()
        { 
            confirmDialog("Info","Added an HPC Sliver to Site ");
        },
        //error:function (xhr, textStatus, thrownError){
         //   alert("error doing something");
        //}
    });
  //  confirmDialog("Add HPC Slivers","Add some HPC Slivers to site " + $(this).data('site'));
});

function getIcon(numNodes, numHPCSlivers, currentBW, hot) {
    //var colorChoices = ["#007FFF", "#0000FF", "#7f00ff", "#FF00FF", "#FF007F", "#FF0000"];
    var colorChoices = ["#0000FF", "#00FFFF", "#00FF00", "#FFFF00", "#FF0000"];

    var ratio = hot * 100; //(numHPCSlivers/numNodes) * 100;
    var numColors = colorChoices.length;
    var colorBands = 100/numColors;

    //Algorithm for color tone should consider the number of available nodes
    // on the site, and then how much the current dedicated nodes are impacted
    //var iconColor = 0;
    var iconColor = colorChoices.length-1;
    for (colorBand = 0; colorBand < numColors; colorBand ++) {
        if (ratio < colorBands * colorBand+1) {
            iconColor = colorBand
            break;
        }
    }

    if (numHPCSlivers < 1) {
        iconColor = "#7F7F7F";
    } else {
        iconColor = colorChoices[iconColor];
    }

    var icon = L.MakiMarkers.icon({icon: "star-stroked", color: iconColor , size: "s"});
    return icon;
}

function updateMaps() {
    log.debug("Attempting to update Maps");
    $.ajax({
    url : '/hpcdashboard',
    dataType : 'json',
    type : 'GET',
    success: function(newData)
    {
        log.debug("Successfully got data back...");
        log.debug(newData);
        log.debug("Still have old data too");
        log.debug(mapData);
        updateMapData(newData);
    }
});
    setTimeout(updateMaps, 30000)

}

function updateMapData(newData) {
    for ( site in newData ) {
        var isNewSite = false;
        //check to see if the site is new or not
        if (site in mapData) {
            log.debug("Site " + site + " already mapped");
            //take ownership of marker
            newData[site]['marker'] = mapData[site]['marker'];
            delete mapData[site];
            newData[site]['marker'].setIcon(getIcon(newData[site]['numNodes'], newData[site]['numHPCSlivers'],  0, newData[site]['hot']));
            // workaround, markers currently don't have a setPopup Content method -- so have to grab object directly
            newData[site]['marker']._popup.setContent(setPopupVals(site, newData[site]));
        }
        else {
            isNewSite = true;
            log.debug("New Site detected: " + site);
            newData[site]['marker'] = L.marker([newData[site]['lat'], newData[site]['long']], 
                                              {icon: getIcon(newData[site]['numNodes'], newData[site]['numHPCSlivers'],  0, newData[site]['hot']) });
            newData[site]['marker'].addTo(map).bindPopup(setPopupVals(site, newData[site])); //.openPopup();
            log.debug("Should have added the new site");

        }
    }

    // Anything still in data needs to be removed since it is no longer a valid site
    for (remSite in mapData) {
        log.warn("Site: " + remSite + " is no longer valid, removing from map");
        map.removeLayer(data[remSite]['marker']);
    }
    mapData = newData;
}

function onMapClick(e) {
    popup
    .setLatLng(e.latlng)
    .setContent("You clicked the map at " + e.latlng.toString())
    .openOn(map);
}

setTimeout(updateMaps, 5000)

// from stackexchange
function setInnerText (elementId, text) {
    var element;
    if (document.getElementById) {
        element = document.getElementById(elementId);
    } else if (document.all) {
        element = document.all[elementId];
    }
    if (element) {
        if (typeof element.textContent != 'undefined') {
            element.textContent = text;
        } else if (typeof element.innerText != 'undefined') {
            element.innerText = text;
        } else if (typeof element.removeChild != 'undefined') {
            while (element.hasChildNodes()) {
                element.removeChild(element.lastChild);
            }
            element.appendChild(document.createTextNode(text)) ;
        }
    }
}

function updateLabelData(summaryData) {
    setInnerText("active-slivers-value", summaryData["total_slivers"]);
    setInnerText("overall-throughput-value", (summaryData["total_bandwidth"]*8/1024/1024/1024).toFixed(2) + " Gbps");
    setInnerText("cpu-utilization-value", summaryData["average_cpu"] + "%");
}

function updateLabels() {
    log.debug("Attempting to update Labels");
    $.ajax({
    url : '/hpcsummary',
    dataType : 'json',
    type : 'GET',
    success: function(newData)
    {
        updateLabelData(newData);
    }
});
    setTimeout(updateLabels, 30000)

}

setTimeout(updateLabels, 5000)
		

</script>
{% endblock %}
