<!DOCTYPE html>
<head>
    <meta charset="utf-8">

    <script src="vendor/d3/d3.v3.js"></script>

    <link href="vendor/bootstrap/css/bootstrap.css" rel="stylesheet" type="text/css">

    <style type="text/css">
         table td:nth-child(2) {
             white-space: nowrap;
         }
    </style>
</head>

<body>

<div class="container">
    <div class="page-header">
        <h1>Presto</h1>
    </div>

    <table id="running" class="table table-striped">
        <thead>
        <tr>
            <th>Id</th>
            <th>Elapsed</th>
            <th>Query</th>
            <th>Source</th>
            <th>User</th>
            <th>State</th>
            <th>Progress</th>
            <th>Queued</th>
            <th>Running</th>
            <th>Done</th>
        </tr>
        </thead>
        <tbody></tbody>
    </table>

    <table id="done" class="table table-striped">
        <thead>
        <tr>
            <th>Id</th>
            <th>Elapsed</th>
            <th>Query</th>
            <th>Source</th>
            <th>User</th>
            <th>State</th>
            <th>Done</th>
            <th>Total</th>
            <th>Completion</th>
        </tr>
        </thead>
        <tbody></tbody>
    </table>
</div>

</body>

<script>

function redraw()
{
    d3.json('/v1/query', function (queries)
    {
        var runningQueries = [];
        var doneQueries = [];
        if (queries) {
            runningQueries = queries.filter(function (query)
            {
                return query.state != 'FINISHED' && query.state != 'FAILED' && query.state != 'CANCELED';
            });

            doneQueries = queries.filter(function (query)
            {
                return query.state == 'FINISHED' || query.state == 'FAILED' || query.state == 'CANCELED';
            });
        }

        renderRunningQueries(runningQueries);
        renderDoneQueries(doneQueries);
    });
}

function renderDoneQueries(queries)
{
    var tbody = d3.select("#done").select("tbody");

    var rows = tbody.selectAll("tr")
            .data(queries, function (query) { return query.queryId; });

    rows.enter()
            .append("tr")
            .attr("class", function (query) {
                          switch (query.state) {
                          case "FINISHED":
                              return "success";
                          case "FAILED":
                              return "error";
                          case "CANCELED":
                              return "warning";
                          default:
                              return "info";
                      }
                  })
            .on("click", function(query) { window.location = "query.html?" + query.queryId });

    rows.exit()
            .remove();

    rows.selectAll("td")
            .data(function (queryInfo) {
                      var splits = queryInfo.totalDrivers;
                      var completedSplits = queryInfo.completedDrivers;

                      var query = queryInfo.query;
                      if (query.length > 200) {
                          query = query.substring(0, 200) + "...";
                      }

                      return [
                          queryInfo.queryId,
                          queryInfo.elapsedTime,
                          query,
                          queryInfo.session.source,
                          queryInfo.session.user,
                          queryInfo.state,
                          completedSplits,
                          splits,
                          d3.format("%")(splits == 0 ? 0 : completedSplits / splits)
                      ]
                  })
            .enter()
            .append("td")
            .text(function (d)
                  {
                      return d;
                  });

    tbody.selectAll("tr")
            .sort(function (a, b) { return d3.descending(a.endTime, b.endTime); });
}

function renderRunningQueries(queries)
{
    var tbody = d3.select("#running").select("tbody");

    var rows = tbody.selectAll("tr")
            .data(queries, function (query) { return query.queryId; })

    rows.exit()
            .remove();

    rows.enter()
            .append("tr")
            .attr("class", "info")
            .on("click", function(query) { window.location = "query.html?" + query.queryId });

    var cells = rows.selectAll("td")
            .data(function (queryInfo)
                  {
                      var splits = queryInfo.totalDrivers;
                      var completedSplits = queryInfo.completedDrivers;

                      var runningSplits = queryInfo.runningDrivers;
                      var queuedSplits = queryInfo.queuedDrivers;

                      var query = queryInfo.query;
                      if (query.length > 200) {
                          query = query.substring(0, 200) + "...";
                      }

                      return [
                          queryInfo.queryId,
                          queryInfo.elapsedTime,
                          query,
                          queryInfo.session.source,
                          queryInfo.session.user,
                          queryInfo.state,
                          d3.format("%")(splits == 0 ? 0 : completedSplits / splits),
                          queuedSplits,
                          runningSplits,
                          completedSplits
                      ]
                  });

    cells.text(function (d) { return d; });

    cells.enter()
            .append("td")
            .text(function (d) { return d; });

    tbody.selectAll("tr")
            .sort(function (a, b) { return d3.descending(a.createTime, b.createTime); });
}

function allStages(stage)
{
    if (stage == undefined) {
        return [];
    }

    if (stage.subStages.length == 0) {
        return [stage];
    }

    var substages = stage.subStages.map(function (substage) { return allStages(substage); });
    return [stage].concat(flatten(substages));
}


function flatten(array)
{
    return [].concat.apply([], array);
}

setInterval(function () { redraw(); }, 1000);

redraw();

</script>
