'use strict';

angular.module('etcdStats', ['ngRoute', 'etcd'])

.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: 'views/stats.html',
      controller: 'StatsCtrl'
    })
    .otherwise({
      templateUrl: 'views/stats.html',
      controller: 'StatsCtrl'
    });
}])

.controller('StatsCtrl', ['$scope', 'EtcdV2', 'statsVega', function ($scope, EtcdV2, statsVega) {
  $scope.graphContainer = '#latency';
  $scope.graphVisibility = 'etcd-graph-show';
  $scope.tableVisibility = 'etcd-table-hide';

  //make requests
  function readStats() {
    EtcdV2.getStat('leader').get().success(function(data) {
      $scope.leaderStats = data;
      $scope.leaderName = data.leader;
      $scope.peers = [];
      //hardcode leader stats
      $scope.peers.push({
        latency: {
          average: 0,
          current: 0,
          minimum: 0,
          maximum: 0,
          standardDeviation: 0
        },
        name: data.leader
      });
      $.each(data.followers, function(index, value) {
        value.name = index;
        $scope.peers.push(value);
      });
      //sort array so peers don't jump when output
      $scope.peers.sort(function(a, b){
          if(a.name < b.name) return -1;
          if(a.name > b.name) return 1;
          return 0;
      });
      drawGraph();
    });
  }

  function drawGraph () {
    //hardcoded padding from chart json
    var vertPadding = 30;
    var horzPadding = 15;
    //fetch width and height of graph area
    var width = $($scope.graphContainer).width() - horzPadding;
    var height = $($scope.graphContainer).height() - vertPadding;

    // parse a spec and create a visualization view
    function parse(spec) {
      vg.parse.spec(spec, function(chart) {
        chart({
          el: $scope.graphContainer,
          data: {
            'stats': $scope.peers
          }
        }).width(width).height(height).update();
      });
    }
    parse(statsVega);
  }

  $scope.showTable = function() {
    $scope.tableVisibility = 'etcd-table-reveal';
  };

  $scope.showGraph = function() {
    $scope.tableVisibility = 'etcd-table-hide';
  };

  $scope.getHeight = function() {
    return $(window).height();
  };
  $scope.getWidth = function() {
    return $(window).width();
  };
  $scope.$watch($scope.getHeight, function() {
    $('.etcd-body').css('height', $scope.getHeight()-5);
    readStats();
  });
  $scope.$watch($scope.getWidth, function() {
    readStats();
  });
  window.onresize = function(){
    $scope.$apply();
  };

  // Update the graphs live
  setInterval(function() {
    readStats();
    $scope.$apply();
  }, 500);
}])


/* statsVega returns the vega configuration for the stats dashboard */
.factory('statsVega', function () {
  return {
    'padding': {'top': 10, 'left': 5, 'bottom': 40, 'right': 10},
    'data': [
      {
        'name': 'stats'
      },
      {
        'name': 'thresholds',
        'values': [50, 100]
      }
    ],
    'scales': [
      {
        'name': 'y',
        'type': 'ordinal',
        'range': 'height',
        'domain': {'data': 'stats', 'field': 'index'}
      },
      {
        'name': 'x',
        'range': 'width',
        'domainMin': 0,
        'domainMax': 100,
        'nice': true,
        'zero': true,
        'domain': {'data': 'stats', 'field': 'data.latency.current'}
      },
      {
        'name': 'color',
        'type': 'linear',
        'domain': [10, 50, 100, 1000000000],
        'range': ['#00DB24', '#FFC000', '#c40022', '#c40022']
      }
    ],
    'axes': [
      {
        'type': 'x',
        'scale': 'x',
        'ticks': 6,
        'name': 'Latency (ms)'
      },
      {
        'type': 'y',
        'scale': 'y',
        'properties': {
          'ticks': {
            'stroke': {'value': 'transparent'}
          },
          'majorTicks': {
            'stroke': {'value': 'transparent'}
          },
          'labels': {
            'fill': {'value': 'transparent'}
          },
          'axis': {
            'stroke': {'value': '#333'},
            'strokeWidth': {'value': 1}
          }
        }
      }
    ],
    'marks': [
      {
        'type': 'rect',
        'from': {'data': 'stats'},
        'properties': {
          'enter': {
            'x': {'scale': 'x', 'value': 0},
            'x2': {'scale': 'x', 'field': 'data.latency.current'},
            'y': {'scale': 'y', 'field': 'index', 'offset': -1},
            'height': {'value': 3},
            'fill': {'scale':'color', 'field':'data.latency.current'}
          }
        }
      },
      {
          'type': 'symbol',
          'from': {'data': 'stats'},
          'properties': {
            'enter': {
              'x': {'scale': 'x', 'field': 'data.latency.current'},
              'y': {'scale': 'y', 'field': 'index'},
              'size': {'value': 50},
              'fill': {'value': '#000'}
            }
          }
        }
      ]
    };
});
