<!doctype html>
<html ng-app="Application">

  <head>
    <script>
        var OSProfilerData = $DATA
    </script>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
    <script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>

    <style>
      .trace {
        min-width: 900px;
        width: 100%;
      }
      .trace tr:hover {
        background-color: #D9EDF7!important;
      }
      .trace tr td {
        width: 14%;
        white-space: nowrap;
        padding: 2px;
        border-right: 1px solid #eee;
      }
      .trace tr td.details {
        width: 10%;
        padding-right: 20px;
      }
      .trace.cursor_pointer_on_hover {
        cursor: pointer;
      }
      .trace .level {
        width: 10%;
        font-weight: bold;
      }
      .bold {
        font-weight: bold;
      }
      .duration {
        width: 25px;
        margin: 0px;
        padding: 0px;
        background-color: #c6eff3;
        border-radius: 4px;
        font-size: 10px;
      }
      .duration div{
        padding-top: 4px;
        padding-bottom: 4px;
        text-align: center;
      }
    </style>

    <script type="text/ng-template"  id="tree_item_renderer.html">

        <div ng-init="hide_children=false">
          <table class="trace cursor_pointer_on_hover">
            <tr>
              <td class="level" style="padding-left:{{data.level * 5}}px;">
                <button type="button" class="btn btn-default btn-xs" ng-disabled="data.is_leaf" ng-click="hide_children=!hide_children">
                  <span class="glyphicon glyphicon-{{ (data.is_leaf) ? 'cloud' : ((hide_children) ? 'plus': 'minus')}}"></span>
                  {{data.level || 0}}
                </button>
              </td>
              <td ng-click="display(data);" class="text-center">
               <div class="duration" style="width: {{get_width(data)}}%; margin-left: {{get_started(data)}}%">
                  <div>{{data.info.finished - data.info.started}} ms</div>
                </div>
              </td>
              <td ng-click="display(data);" class="{{ is_important(data) ? 'bold' : ''}} text-right" > {{data.info.name}} </td>
              <td ng-click="display(data);"> {{data.info.project  || "n/a"}}</td>
              <td ng-click="display(data);"> {{data.info.service  || "n/a" }} </td>
              <td ng-click="display(data);"> {{data.info.host || "n/a"}} </td>
              <td class="details">
                <a href="#" ng-click="display(data);"> Details </a>
              </td>
            </tr>
          </table>

        <div ng-hide="hide_children">
          <div ng-repeat="data in data.children" ng-include="'tree_item_renderer.html'"> </div>
        </div>
      </div>

    </script>

    <script>
      angular.module("Application", ['ui.bootstrap']);

      function ProfilerCtlr($scope, $modal) {

        var convert_input = function(input, level){
          level = (level) ? level : 0;
          input.level = level;
          input.is_leaf = !input.children.length

          for (var i=0; i < input.children.length; i++)
            convert_input(input.children[i], level + 1);
          return input;
        }

        $scope.get_width = function(data){

          var full_duration = $scope.tree[0].info.finished;
          var duration = (data.info.finished - data.info.started) * 100.0 / full_duration;
          return (duration >= 0.5) ? duration : 0.5;
        }

        $scope.get_started = function(data) {
          var full_duration = $scope.tree[0].info.finished;
          return data.info.started * 100.0 / full_duration;
        }

        $scope.is_important = function(data) {
          return ["total", "wsgi", "rpc"].indexOf(data.info.name) != -1;
        }

        $scope.display = function(data){
          var info = angular.copy(data.info);

          var metadata = {};
          angular.forEach(info, function(value, key) {
            var parts = key.split(".");
            if (parts[0] == "meta"){

              if (parts.length == 2){
                this[parts[1]] = value;
              }
              else{
                var group_name = parts[1];
                if (!(group_name in this))
                  this[group_name] = {};

                this[group_name][parts[2]] = value;
              }
            };
          }, metadata);

          info["duration"] = info["finished"] - info["started"]
          info["metadata"] = "<pre>" + JSON.stringify(metadata, "", 4) + "</pre>"

          var trace_data = "<div class='row'>"
          columns = ["name", "project", "service", "host", "started",
                     "finished", "duration", "metadata"];
          for (var i = 0; i < columns.length; i++){
            trace_data += "<div class='col-md-2 text-right text-capitalize'><strong>" + columns[i] + " </strong></div>";
            trace_data += "<div class='col-md-10 text-left'>" + info[columns[i]] + "</div>";
          }
          trace_data += "</div>";

          var output = (
            '<div class="modal-header"> Trace Point Details </div>' +
            '<div class="modal-body">' + trace_data + '</div>' +
            '<div class="modal-footer"> <span class="glyphicon glyphicon-cloud </div>'
          );

          var modal_instance = $modal.open({
            "template": output,
            "size": "lg"
          });
        }

        $scope.tree = [convert_input(OSProfilerData)];
      }

    </script>
  </head>

  <body>
    <div ng-controller="ProfilerCtlr">
      <table class="trace">
        <tr class="bold text-left" style="border-bottom: solid 1px gray">
          <td class="level">Levels</td>
          <td>Duration</td>
          <td class="text-right">Type</td>
          <td>Project</td>
          <td>Service</td>
          <td>Host</td>
          <td class="details">Details</td>
        </tr>
      </table>
      <div ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></div>
    </div>

  </body>

</html>
