# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Disable the line-too-long warning.
# pylint: disable=C0301
"""This module implements the Chromium Performance Dashboard JSON v1.0 data
format.

See http://www.chromium.org/developers/speed-infra/performance-dashboard/sending-data-to-the-performance-dashboard.
"""

import httplib
import json
import pprint
import subprocess
import urllib
import urllib2


_LOCAL_SERVER = "http://127.0.0.1:8080"


class ChartDataRecorder(object):
  """Allows one to record measurement values one by one and then generate the
  JSON string that represents them in the 'chart_data' format expected by the
  performance dashboard.
  """

  def __init__(self, benchmark_name):
    self.charts = {}
    self.benchmark_name = benchmark_name

  def record_scalar(self, chart_name, value_name, units, value):
    """Records a single measurement value of a scalar type."""
    if chart_name not in self.charts:
      self.charts[chart_name] = {}
    self.charts[chart_name][value_name] = {
        'type': 'scalar',
        'units': units,
        'value': value}

  def get_chart_data(self):
    """Returns the JSON string representing the recorded chart data, wrapping
    it with the required meta data."""
    chart_data = {
        'format_version': '1.0',
        'benchmark_name': self.benchmark_name,
        'charts': self.charts
    }
    return chart_data


def add_argparse_server_arguments(parser):
  """Adds argparse arguments needed to upload the chart data to a performance
  dashboard to the given parser.
  """
  dashboard_group = parser.add_argument_group('Performance dashboard server',
      'These arguments allow to specify the performance dashboard server '
      'to upload the results to.')

  dashboard_group.add_argument(
      '--upload', action='store_true',
      help='Upload the results to performance dashboard. Further arguments '
           'in this group are relevant only if --upload is passed.')
  dashboard_group.add_argument(
      '--server-url',
      help='Url of the server instance to upload the results to. By default a '
           'local instance is assumed to be running on port 8080.')
  dashboard_group.add_argument(
      '--master-name',
      help='Buildbot master name, used to construct link to buildbot log by '
           'the dashboard, and also as the top-level category for the data.')
  dashboard_group.add_argument(
      '--bot-name',
      help='Used as the second-level category for the data.')
  dashboard_group.add_argument(
      '--test-name',
      help='Name of the test that the perf data was generated from.')
  dashboard_group.add_argument(
      '--builder-name',
      help='Buildbot builder name, used to construct link to buildbot log by '
           'the dashboard.')
  dashboard_group.add_argument(
      '--build-number', type=int,
      help='Build number, used to construct link to buildbot log by the '
           'dashboard.')
  dashboard_group.add_argument(
      '--dry-run', action='store_true', default=False,
      help='Display the server URL and the data to upload, but do not actually '
           'upload the data.')


def normalize_label(label):
  """Normalizes a label to be used for data sent to performance dashboard.

  This replaces:
    '/' -> '-', as slashes are used to denote test/sub-test relation.
    ' ' -> '_', as there is a convention of not using spaces in test names.

  Returns:
    Normalized label.
  """
  return label.replace('/', '-').replace(' ', '_')


def _get_commit_count():
  """Returns the number of git commits in the repository of the cwd."""
  return subprocess.check_output(
      ['git', 'rev-list', 'HEAD', '--count']).strip()


def _get_current_commit():
  """Returns the hash of the current commit in the repository of the cwd."""
  return subprocess.check_output(["git", "rev-parse", "HEAD"]).strip()


class _UploadException(Exception):
  pass


def _upload(server_url, json_data):
  """Make an HTTP POST with the given data to the performance dashboard.

  Args:
    server_url: URL of the performance dashboard instance.
    json_data: JSON string that contains the data to be sent.

  Raises:
    _UploadException: An error occurred during uploading.
  """
  # When data is provided to urllib2.Request, a POST is sent instead of GET.
  # The data must be in the application/x-www-form-urlencoded format.
  data = urllib.urlencode({"data": json_data})
  req = urllib2.Request("%s/add_point" % server_url, data)
  try:
    urllib2.urlopen(req)
  except urllib2.HTTPError as e:
    raise _UploadException('HTTPError: %d. Response: %s\n'
                           'JSON: %s\n' % (e.code, e.read(), json_data))
  except urllib2.URLError as e:
    raise _UploadException('URLError: %s for JSON %s\n' %
                           (str(e.reason), json_data))
  except httplib.HTTPException as e:
    raise _UploadException('HTTPException for JSON %s\n' % json_data)


def upload_chart_data(master_name, bot_name, test_name, builder_name,
                      build_number, chart_data, server_url=None, dry_run=False):
  """Uploads the provided chart data to an instance of performance dashboard.
  See the argparse help above for description of the arguments.


  Returns:
    A boolean value indicating whether the operation succeeded or not.
  """

  if (not master_name or not bot_name or not test_name or not builder_name or
      not build_number):
    print ('Cannot upload perf data to the dashboard because not all of the '
           'following values are specified: master-name, bot-name, test_name, '
           'builder-name, build-number.')
    return False

  point_id = _get_commit_count()
  cur_commit = _get_current_commit()

  # Wrap the |chart_data| with meta data as required by the spec.
  formatted_data = {
      'master': master_name,
      'bot': bot_name,
      'masterid': master_name,
      'buildername': builder_name,
      'buildnumber': build_number,
      'versions': {
          'mojo': cur_commit,
      },
      'point_id': point_id,
      'supplemental': {},
      'chart_data': chart_data,
  }

  upload_url = server_url if server_url else _LOCAL_SERVER

  if dry_run:
    print 'Will not upload because --dry-run is specified.'
    print 'Server: %s' % upload_url
    print 'Data:'
    pprint.pprint(formatted_data)
  else:
    print 'Uploading data to %s ...' % upload_url
    try:
      _upload(upload_url, json.dumps(formatted_data))
    except _UploadException as e:
      print e
      return False

    print "Done."

    dashboard_params = urllib.urlencode({
        'masters': master_name,
        'bots': bot_name,
        'tests': test_name,
        'rev': point_id
    })
    print 'Results Dashboard: %s/report?%s' % (upload_url, dashboard_params)

  return True
