{% 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>Allocated Slivers:</b> <span id="active-slivers-value"> </span> </span>
        <span class="summary-attr"><b>Bytes Served:</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">
{% include "/opt/planetstack/templates/admin/dashboard/tenant.html" %}
</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 %}
