/*
 * 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.
 */

/*
 * Licensed under the Apache License, Version 2.0
 * See accompanying LICENSE file.
 */

angular.module('dashboard')

  .directive('metricsCharts', function () {
    'use strict';

    return {
      restrict: 'E',
      templateUrl: 'views/apps/streamingapp/metrics_charts.html',
      scope: true, // inherit parent scope
      controller: ['$scope', '$interval', 'helper', 'models', function ($scope, $interval, helper, models) {
        'use strict';

        var metricsProvider = $scope.dag;
        var processorId;
        $scope.chartGridClass = 'col-sm-12';
        if ($scope.processor) {
          processorId = $scope.processor.id;
          $scope.chartGridClass = 'col-sm-6';
          $scope.sendThroughputMetricsCaption = 'Message Send Throughput';
          $scope.sendThroughputMetricsDescription = '';
          $scope.receiveThroughputMetricsCaption = 'Message Receive Throughput';
          $scope.receiveThroughputMetricsDescription = '';
          $scope.messageLatencyMetricsCaption = 'Average Message Receive Latency';
          $scope.messageLatencyMetricsDescription = '';
        }
        var sc = $scope.metricsConfig;
        var recentChartPoints = sc.retainRecentDataSeconds * 1000 / sc.retainRecentDataIntervalMs;
        var histChartPoints = sc.retainHistoryDataHours * 3600 * 1000 / sc.retainHistoryDataIntervalMs;
        recentChartPoints--; // ProcessorFilter will actually reduce one point
        histChartPoints--;
        var updateRecentMetricsPromise;
        $scope.$on('$destroy', function () {
          $interval.cancel(updateRecentMetricsPromise);
        });

        // part 1
        function createChart(unit, visibleDataPointsNum, dataPoints) {
          return {
            options: {
              height: '108px',
              margin: {right: 30},
              seriesNames: [''],
              yAxisLabelFormatter: helper.yAxisLabelFormatterWithoutValue0(),
              visibleDataPointsNum: visibleDataPointsNum,
              data: dataPoints,
              valueFormatter: function (value) {
                return helper.readableMetricValue(value) + ' ' + unit;
              }
            },
            data: null
          };
        }

        function createThroughputChart(visibleDataPointsNum, dataPoints) {
          return createChart('msg/s', visibleDataPointsNum, dataPoints);
        }

        function createDurationChart(visibleDataPointsNum, dataPoints) {
          return createChart('ms', visibleDataPointsNum, dataPoints);
        }

        $scope.sendThroughputChart = createThroughputChart(recentChartPoints);
        $scope.receiveThroughputChart = createThroughputChart(recentChartPoints);
        $scope.averageProcessingTimeChart = createDurationChart(recentChartPoints);
        $scope.messageReceiveLatencyChart = createDurationChart(recentChartPoints);

        function redrawMetricsCharts() {

          function _rebuildChartWithNewDataPoints(chartOptions, metrics) {
            var all = !$scope.isShowingCurrentMetrics;
            var dataPoints = metricsToChartData(metrics);
            var visibleDataPointsNum = all ?
              Math.max(dataPoints.length, histChartPoints) : recentChartPoints;
            if (all && dataPoints.length < 2) {
              // Hide chart data, if there is only one data point there, which looks very ugly.
              visibleDataPointsNum = 0;
              dataPoints = [];
            }
            // Rebuild the chart
            chartOptions.data = dataPoints;
            chartOptions.visibleDataPointsNum = visibleDataPointsNum;
          }

          if (!$scope.isShowingCurrentMetrics) {
            $interval.cancel(updateRecentMetricsPromise);
          }

          var queryMetricsPromise = $scope.isShowingCurrentMetrics ?
            models.$get.appMetrics($scope.app.appId, $scope.metricsConfig.retainRecentDataIntervalMs) :
            models.$get.appHistMetrics($scope.app.appId);

          queryMetricsPromise.then(function (metrics) {
            var data = metrics.$data();
            var timeResolution = $scope.isShowingCurrentMetrics ?
              $scope.metricsConfig.retainRecentDataIntervalMs :
              $scope.metricsConfig.retainHistoryDataIntervalMs;
            metricsProvider.replaceHistoricalMetrics(data, timeResolution);

            if (angular.isNumber(processorId)) {
              _rebuildChartWithNewDataPoints($scope.sendThroughputChart.options,
                metricsProvider.getProcessorHistoricalMessageSendThroughput(processorId));
              _rebuildChartWithNewDataPoints($scope.receiveThroughputChart.options,
                metricsProvider.getProcessorHistoricalMessageReceiveThroughput(processorId));
              _rebuildChartWithNewDataPoints($scope.averageProcessingTimeChart.options,
                metricsProvider.getProcessorHistoricalAverageMessageProcessingTime(processorId));
              _rebuildChartWithNewDataPoints($scope.messageReceiveLatencyChart.options,
                metricsProvider.getProcessorHistoricalAverageMessageReceiveLatency(processorId));
            } else {
              _rebuildChartWithNewDataPoints($scope.sendThroughputChart.options,
                metricsProvider.getSourceProcessorHistoricalMessageSendThroughput());
              _rebuildChartWithNewDataPoints($scope.receiveThroughputChart.options,
                metricsProvider.getSinkProcessorHistoricalMessageReceiveThroughput());
              _rebuildChartWithNewDataPoints($scope.messageReceiveLatencyChart.options,
                metricsProvider.getHistoricalCriticalPathLatency());
            }

            if ($scope.isShowingCurrentMetrics) {
              updateRecentMetricsPromise = $interval(fillChartsWithCurrentMetrics,
                sc.retainRecentDataIntervalMs);
            }
          });
        }

        function fillChartsWithCurrentMetrics() {

          function _data(metric, metricTime) {
            var metrics = {};
            metrics[metricTime] = [metric];
            return metricsToChartData(metrics);
          }

          var timeResolution = $scope.metricsConfig.retainRecentDataIntervalMs;
          var metricTime = Math.floor(metricsProvider.metricsUpdateTime / timeResolution) * timeResolution;
          $scope.sendThroughputChart.data = _data($scope.currentMessageSendRate, metricTime);
          $scope.receiveThroughputChart.data = _data($scope.currentMessageReceiveRate, metricTime);
          $scope.averageProcessingTimeChart.data = _data($scope.averageProcessingTime, metricTime);
          $scope.messageReceiveLatencyChart.data = _data($scope.messageReceiveLatency, metricTime);
        }

        function metricsToChartData(metrics) {
          return _.map(metrics, function (value, timeString) {
            return {
              x: helper.timeToChartTimeLabel(Number(timeString), /*shortForm=*/$scope.isShowingCurrentMetrics),
              y: helper.metricRounded(value)
            };
          });
        }

        $scope.isShowingCurrentMetrics = true;
        $scope.$watch('isShowingCurrentMetrics', function (newVal, oldVal) {
          if (angular.equals(newVal, oldVal)) {
            return; // ignore initial notification
          }
          redrawMetricsCharts();
        });

        // common watching
        var initial = true;
        $scope.$watch('dag.metricsUpdateTime', function () {
          if (initial) {
            // note that, the latest metrics do not contain enough points for drawing charts, so
            // we request recent metrics from server.
            redrawMetricsCharts();
            initial = false;
          }

          updateMetricCards();
        });

        function updateMetricCards() {
          var sentMessages, receivedMessages;
          if (angular.isNumber(processorId)) {
            sentMessages = metricsProvider.getProcessorSentMessages(processorId);
            receivedMessages = metricsProvider.getProcessorReceivedMessages(processorId);
            $scope.averageProcessingTime = metricsProvider.getProcessorAverageMessageProcessingTime(processorId);
            $scope.messageReceiveLatency = metricsProvider.getProcessorMessageReceiveLatency(processorId);
          } else {
            sentMessages = metricsProvider.getSourceProcessorSentMessageTotalAndRate();
            receivedMessages = metricsProvider.getSinkProcessorReceivedMessageTotalAndRate();
            $scope.messageReceiveLatency = metricsProvider.getCriticalPathLatency();
          }
          $scope.currentMessageSendRate = sentMessages.rate;
          $scope.currentMessageReceiveRate = receivedMessages.rate;
          $scope.totalSentMessages = sentMessages.total;
          $scope.totalReceivedMessages = receivedMessages.total;
        }
      }]
    };
  })
;
