/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * Generate the stats rollup table.
 */
(function (global) {
  function drawStatsTable(planController, baseUrl, cluster, environ, toponame, physicalPlan, logicalPlan) {
    var NO_DATA_COLOR = "#f0f5fa";

    var table = d3.selectAll('.stat-rollup-table tbody.stats');
    var percentFormat = d3.format('.1%');

    var d3instances = d3.selectAll('#physical-plan .instance');
    var d3instancedata = d3instances.data();

    // Build the status table
    var rowData = [
      {
        name: 'Capacity',
        metricName: 'capacity',
        get: getAndRenderStats,
        tooltip: 'Average tuple execute latency multiplied by number of tuples processed divided by the time period.',
        legendDescription: 'capacity',
        loMedHi: [0.1, 0.5, 1],
        scaleTicks: [0, 0.25, 0.5, 0.75, 1]
      },
      {
        name: 'Failures',
        metricName: 'failures',
        get: getAndRenderStats,
        tooltip: 'Failed tuple count divided by sum of failed and executed tuples over time range.',
        legendDescription: 'failure rate',
        loMedHi: [0, 0.02, 0.05],
        scaleTicks: [0, 0.01, 0.02, 0.03, 0.04, 0.05]
      },
      {
        name: 'CPU',
        metricName: 'cpu',
        get: getAndRenderStats,
        tooltip: 'CPU seconds used per second.',
        legendDescription: 'CPUs used',
        loMedHi: [1, 1.5, 2],
        scaleTicks: [0, 0.5, 1, 1.5, 2],
        format: function (d) { return d.toFixed(2); }
      },
      {
        name: 'Memory',
        metricName: 'memory',
        get: getAndRenderStats,
        tooltip: 'Memory used divided by total available memory per process.',
        legendDescription: 'memory usage',
        loMedHi: [0.7, 0.85, 1],
        scaleTicks: [0, 0.25, 0.5, 0.75, 1],
      },
      {
        name: 'GC',
        metricName: 'gc',
        get: getAndRenderStats,
        tooltip: 'Milliseconds spent in garbage collection per minute.',
        legendDescription: 'ms in GC per minute',
        loMedHi: [1000, 1500, 2000],
        scaleTicks: [0, 500, 1000, 1500, 2000],
        format: function (d) { return d.toFixed(0); }
      },
      {
        name: 'Back Pressure',
        metricName: 'backpressure',
        get: getAndRenderStats,
        tooltip: 'Milliseconds spent in back pressure per minute.',
        legendDescription: 'ms in back pressure per minute',
        loMedHi: [3000, 12000, 30000],
        scaleTicks: [0, 7500, 15000, 22500, 30000],
        format: function (d) { return d.toFixed(0); }
      }
    ];

    var colData = [
      {name: '3 min', seconds: 3*60},
      {name: '10 min', seconds: 10*60},
      {name: '1 hour', seconds: 60*60},
      {name: '3 hours', seconds: 3*60*60}
    ];
    window.pollingMetrics = rowData;
    window.pollingPeriods = colData;

    var colorRanges = {
      // green/red
      'default': ['#1a9850', '#fdae61', '#d73027'],
      // blue/red
      'colorblind': ['#2166ac', '#f7f7f7', '#b2182b']
    };

    rowData.forEach(function (d) {
      d.format = d.format || d3.format('%');
      d.colorScale = d3.scale.linear()
          .interpolate(d3.interpolateLab)
          .domain(d.loMedHi)
          .range(colorRanges[localStorage.colors] || colorRanges.default)
          .clamp(true);
    });

    var rows = table.selectAll('tr')
        .data(rowData)
        .enter()
      .append('tr');

    rows.append('td')
        .attr('class', 'text-right')
        .html(function (d) {
          return d.name + ' <span class="glyphicon glyphicon-question-sign bs-popover text-muted" aria-hidden="true" data-toggle="popover" data-placement="top" title="' + d.name + '" data-content="' + d.tooltip + '"></span></a>';
        });

    $('.bs-popover').popover({
      trigger: 'hover',
      container: 'body'
    });

    var cols = rows.selectAll('td.time')
        .data(function (row) {
          return colData.map(function (col) {
            return {
              metric: row,
              time: col
            };
          });
        })
        .enter()
      .append('td')
        .attr('class', 'time');

    var links = cols.append('a')
      .attr('href', '#')
      .attr('class', 'strong')
      .on('click', function (d) {
        d.metric.get(d);
        d3.event.preventDefault();
        d3.event.stopPropagation();
      });

    var topLevelStatus = links.append('svg')
        .attr('class', 'status-circle')
        .attr('width', 20)
        .attr('height', 15)
      .append('circle')
        .attr('cx', 8)
        .attr('cy', 8)
        .attr('r', 7);

    links.append('span')
        .text(function (d) { return d.time.name; });

    d3.selectAll('.reset').on('click', function () {
      resetColors();
    });

    d3.selectAll('#reset-colors').on('click', function () {
      resetColors();
      d3.event.stopPropagation();
      d3.event.preventDefault();
    });

    // Start polling once a minute for all top-level stats
    function fillInTopLevelStats() {
      topLevelStatus.each(function (d) {
        d.metric.get(d, true);
      });
    }
    // If there are more than 20 logical nodes or 400 physical instances, don't request metrics automatically
    // instead wait for the user to click on them to fill in.
    setTimeout(function () {
      if (d3.selectAll('#logical-plan .node').size() <= 20 && d3.selectAll('#physical-plan .instance').size() <= 400) {
        fillInTopLevelStats();
        setInterval(fillInTopLevelStats, 60000);
      }
    }, 20);

    function getAndRenderStats(statTableCell, justFillInTopLevel) {
      var seconds = statTableCell.time.seconds;
      var durationString = statTableCell.time.name;

      if (!justFillInTopLevel) {
        drawColorKey(statTableCell);
        clearComponentColors(statTableCell);
      }
      makeMetricsQuery(statTableCell.metric, seconds / 60, function (data) {
        var max = d3.max(data, function (d) { return d.value; });
        _.pairs(_.groupBy(data, 'name')).forEach(function (pair) {
          var name = pair[0];
          var values = _.pluck(pair[1], 'value');
          var maxValue = d3.max(values);
          pair[1].forEach(function (datapoint) {
            recordInstanceMetric(datapoint.value, datapoint.id, statTableCell);
          });
          if (!justFillInTopLevel) {
            colorGraphNodes(maxValue, name, statTableCell);
            pair[1].forEach(function (datapoint) {
              colorInstances(datapoint.value, datapoint.id, statTableCell);
            });
          }
        });
        colorTopLevel(max, statTableCell);
      });
    }

    // Re-render the color key based on current metric displayed
    function drawColorKey(statTableCell) {
      var parentSelector = '#color-key';
      var tickValues = statTableCell.metric.scaleTicks;
      var gradientID = 'colorKey';
      var height = 3;
      var outerWidth = 400;
      var outerHeight = 70;
      var margin = {top: 25, left: 50, bottom: 20, right: 50};
      var width = outerWidth - margin.left - margin.right;

      var keyContainer = d3.selectAll(parentSelector);
      var svg = keyContainer.text('').append('svg')
          .attr('width', outerWidth)
          .attr('height', outerHeight)
        .append('g')
          .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

      svg.append('text')
          .attr('y', -10)
          .attr('x', width / 2)
          .style('text-anchor', 'middle')
          .text('Instances colored by ' + statTableCell.metric.legendDescription + ' over last ' + statTableCell.time.name);

      var xScale = d3.scale.linear()
          .domain(d3.extent(tickValues))
          .range([0, width]);

      // encode the color key as a gradient that stretches across the wide rectangle
      d3.selectAll('svg.svgdefs').remove();
      var gradient = d3.select('body')
        .append('svg')
        .attr('class', 'svgdefs')
        .attr('width', 0)
        .attr('height', 0)
        .append("defs", 'defs')
        .append('linearGradient', gradientID)
          .attr("id", gradientID)
          .attr("x1", "0%")
          .attr("y1", "0%")
          .attr("x2", "100%")
          .attr("y2", "0%")
          .attr("spreadMethod", "pad");

      var valueToPercentScale = d3.scale.linear()
          .domain(d3.extent(tickValues))
          .range(["0%", "100%"]);

      gradient.selectAll('stop')
          .data(statTableCell.metric.colorScale.domain())
          .enter()
        .append("svg:stop")
          .attr("offset", valueToPercentScale)
          .attr("stop-color", statTableCell.metric.colorScale)
          .attr("stop-opacity", 1);
      svg.append('rect')
        .attr('width', width)
        .attr('height', height)
        .attr('fill', 'url(#' + gradientID + ')');

      // also label specific points on the color scale
      var colorScaleAxis = d3.svg.axis()
        .scale(xScale)
        .orient('bottom')
        .tickValues(tickValues)
        .tickFormat(statTableCell.metric.format || d3.format('%'))
        .tickSize(2);
      svg
        .append('g')
          .attr('class', 'x axis')
          .attr('transform', function() {return 'translate(' + 0 +',' + height + ')'; })
          .call(colorScaleAxis);
    }

    // Utilities
    function getLogicalComponentNames() {
      var toRequest = {};

      d3.selectAll('#logical-plan .node').each(function (d) {
        if (d.name) {
          toRequest[d.name] = true;
        }
      });

      return _.keys(toRequest);
    }

    function p90(data) {
      return d3.quantile(_.sortBy(data), 0.9);
    }

    function cleanValue(value) {
      return value === 'nan' ? 0 : +value;
    }

    function colorGraphNodes(value, name, statTableCell) {
      d3.selectAll('#logical-plan .node').filter(function (d) {
        return d.name === name;
      }).style('fill', function (d) {
        return d.color = !_.isNumber(value) || isNaN(value) ? NO_DATA_COLOR : statTableCell.metric.colorScale(value);
      });
    }

    function clearComponentColors(statTableCell) {
      d3.selectAll('#physical-plan .instance, #logical-plan .node').style('fill', function (d) {
        d.currentMetric = statTableCell;
        d.currentMetricValue = null;
        return d.color = NO_DATA_COLOR;
      });
    }

    function recordInstanceMetric(value, id, statTableCell) {
      var name = statTableCell.metric.name;
      var seconds = statTableCell.time.seconds;
      var d;
      for (var i = d3instancedata.length - 1; i >= 0; i--) {
        d = d3instancedata[i];
        if (d.id === id) {
          d.stats = d.stats || {};
          d.stats[name] = d.stats[name] || {};
          d.stats[name][seconds] = value;
        }
      }
    }

    function colorInstances(value, id, statTableCell, tooltipDetails) {
      d3.select('html').classed('no-colors', false);
      d3instances.filter(function (d) {
        return id === d.id;
      }).style('fill', function (d) {
        d.currentMetric = statTableCell;
        d.currentMetricValue = value;
        d.tooltipDetails = tooltipDetails;
        return d.color = !_.isNumber(value) || isNaN(value) ? NO_DATA_COLOR : statTableCell.metric.colorScale(value);
      });
    }

    function colorTopLevel(value, statTableCell) {
      topLevelStatus.filter(function (d) {
        return d === statTableCell;
      }).style('fill', function (d) {
        return d.color = !_.isNumber(value) || isNaN(value) ? NO_DATA_COLOR : statTableCell.metric.colorScale(value);
      }).style('visibility', null);
    }

    function resetColors() {
      d3.select('html').classed('no-colors', true);
      d3.select('#color-key').text('');
      d3.selectAll('#physical-plan .instance, #logical-plan .node').style('fill', function (d) {
        d.currentMetric = null;
        d.currentMetricValue = null;
        return d.color = d.defaultColor;
      });
    }

    function createMetricsUrl(metric, component, instance, start, end) {
      var url = baseUrl + '/topologies/metrics/timeline?';
      return [
        url + 'cluster=' + cluster,
        'environ=' + environ,
        'topology=' + toponame,
        'metric=' + metric.metricName,
        'component=' + component,
        'instance=' + instance,
        'starttime=' + start,
        'endtime=' + end
      ].join('&');
    }

    var outstandingRequests = {};

    // slight optimization, instead of requesting metrics for 3m, 10m, 60m, 1h, 3h
    // always request 3 hours of data on first call and attach all simultaneous
    // stats calls to result from the first one and when that responds, parse out
    // the values over last N minutes.

    function makeMetricsQuery(metric, lookbackMinutes, callback) {
      var start = moment().startOf('minute').subtract(lookbackMinutes, 'minutes').valueOf() / 1000;
      doMake3hourMetricsQuery(metric, function (results) {
        var finalResult = results.map(function (d) {
          var values = d.value.filter(function (datapoint) {
            return datapoint.time >= start;
          }).map(function (d) { return d.value; });
          return {
            name: d.name,
            id: d.id,
            value: p90(values)
          };
        });
        callback(finalResult);
      });
    }

    function doMake3hourMetricsQuery(metric, callback) {
      var queryName = metric.name;
      if (outstandingRequests[queryName]) {
        outstandingRequests[queryName].push(callback);
        return;
      }
      var callbacks = [callback];
      outstandingRequests[queryName] = callbacks;
      var start = moment().startOf('minute').subtract(3, 'hours').valueOf() / 1000;
      var end = moment().startOf('minute').valueOf() / 1000;

      fetchMetrics();

      function fetchMetrics() {
        var url = createMetricsUrl(metric, "*", "*", start, end);
        d3.json(url, function (error, data) {
          if (error) {
            console.warn(error);
          }
          var result = [];
          if (data && data.hasOwnProperty("status") && data["status"] === "success" && data.hasOwnProperty("result")) {
            data.result.timeline.forEach(function (timeline) {
              var split = timeline.instance.split('_');
              var values = [];
              for (var timestamp in timeline.data) {
                if (timeline.data.hasOwnProperty(timestamp)) {
                  values.push({
                    time: timestamp,
                    value: timeline.data[timestamp]
                  });
                }
              }
              result.push({
                id: timeline.instance,
                name: split.slice(2, split.length - 1).join('_'),
                value: values
              });
            })
            resolve(result);
          }
        });
      }

      function resolve(data) {
        delete outstandingRequests[queryName];
        callbacks.forEach(function (cb) { cb(data); });
      }
    }
  }

  global.drawStatsTable = drawStatsTable;
}(this));
