# -*- coding: utf-8 -*-
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Uploads performance data to the performance dashboard.

The performance dashboard is owned by Chrome team and is available here:
https://chromeperf.appspot.com/
Users must be logged in with an @google.com account to view perf data there.

For more information on sending data to the dashboard, see:
https://dev.chromium.org/developers/testing/sending-data-to-the-performance-dashboard

Note: This module started off from the autotest/tko/perf_uploader.py but has
been extended significantly since.
"""

from __future__ import print_function

import collections
import httplib
import json
import math
import os
import re
import string
import urllib
import urllib2

from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import retry_util


# Clearly mark perf values coming from chromite by default.
_DEFAULT_TEST_PREFIX = 'cbuildbot.'
_DEFAULT_PLATFORM_PREFIX = 'cros-'
_ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
_PRESENTATION_CONFIG_FILE = os.path.join(_ROOT_DIR,
                                         'perf_dashboard_config.json')

LOCAL_DASHBOARD_URL = 'http://localhost:8080'
STAGE_DASHBOARD_URL = 'https://chrome-perf.googleplex.com'
DASHBOARD_URL = 'https://chromeperf.appspot.com'

_MAX_DESCRIPTION_LENGTH = 256
_MAX_UNIT_LENGTH = 32

# Format for Chrome and Chrome OS version strings.
_VERSION_REGEXP = r'^(\d+)\.(\d+)\.(\d+)\.(\d+)$'

class PerfUploadingError(Exception):
  """A class to wrap errors in this module.

  This exception class has two attributes: value and orig_exc. "value" is what
  was used to create this exception while "orig_exc" is the optional original
  exception that is wrapped by this exception.
  """

  def __init__(self, value, orig_exc=None):
    super(PerfUploadingError, self).__init__(value)
    self.orig_exc = orig_exc

  def __str__(self):
    r = super(PerfUploadingError, self).__str__()
    if self.orig_exc:
      r += '\ncaused by: %s' % str(self.orig_exc)
    return r


PerformanceValue = collections.namedtuple(
    'PerformanceValue',
    'description value units higher_is_better graph stdio_uri')


def OutputPerfValue(filename, description, value, units,
                    higher_is_better=True, graph=None, stdio_uri=None):
  """Record a measured performance value in an output file.

  This is originally from autotest/files/client/common_lib/test.py.

  The output file will subsequently be parsed by ImageTestStage to have the
  information sent to chromeperf.appspot.com.

  Args:
    filename: A path to the output file. Data will be appended to this file.
    description: A string describing the measured perf value. Must
      be maximum length 256, and may only contain letters, numbers,
      periods, dashes, and underscores.  For example:
      "page_load_time", "scrolling-frame-rate".
    value: A number representing the measured perf value, or a list of
      measured values if a test takes multiple measurements. Measured perf
      values can be either ints or floats.
    units: A string describing the units associated with the measured perf
      value(s). Must be maximum length 32, and may only contain letters,
      numbers, periods, dashes, and uderscores. For example: "msec", "fps".
    higher_is_better: A boolean indicating whether or not a higher measured
      perf value is considered better. If False, it is assumed that a "lower"
      measured value is better.
    graph: A string indicating the name of the graph on which the perf value
      will be subsequently displayed on the chrome perf dashboard. This
      allows multiple metrics to be grouped together on the same graph.
      Default to None, perf values should be graphed individually on separate
      graphs.
    stdio_uri: A URL relevant to this data point (e.g. the buildbot log).
  """
  def ValidateString(param_name, value, max_len):
    if len(value) > max_len:
      raise ValueError('%s must be at most %d characters.', param_name, max_len)

    allowed_chars = string.ascii_letters + string.digits + '-._'
    if not set(value).issubset(set(allowed_chars)):
      raise ValueError(
          '%s may only contain letters, digits, hyphens, periods, and '
          'underscores. Its current value is %s.',
          param_name, value
      )

  ValidateString('description', description, _MAX_DESCRIPTION_LENGTH)
  ValidateString('units', units, _MAX_UNIT_LENGTH)

  entry = {
      'description': description,
      'value': value,
      'units': units,
      'higher_is_better': higher_is_better,
      'graph': graph,
      'stdio_uri': stdio_uri,
  }

  data = (json.dumps(entry), '\n')
  osutils.WriteFile(filename, data, 'a')


def LoadPerfValues(filename):
  """Return a list of PerformanceValue objects from |filename|."""
  lines = osutils.ReadFile(filename).splitlines()
  entries = []
  for line in lines:
    entry = json.loads(line)
    entries.append(PerformanceValue(**entry))
  return entries


def _AggregateIterations(perf_values):
  """Aggregate same measurements from multiple iterations.

  Each perf measurement may exist multiple times across multiple iterations
  of a test.  Here, the results for each unique measured perf metric are
  aggregated across multiple iterations.

  Args:
    perf_values: A list of PerformanceValue objects.

  Returns:
    A dictionary mapping each unique measured perf value (keyed by tuple of
      its description and graph name) to information about that perf value
      (in particular, the value is a list of values for each iteration).
  """
  aggregated_data = {}
  for perf_value in perf_values:
    key = (perf_value.description, perf_value.graph)
    try:
      aggregated_entry = aggregated_data[key]
    except KeyError:
      aggregated_entry = {
          'units': perf_value.units,
          'higher_is_better': perf_value.higher_is_better,
          'graph': perf_value.graph,
          'value': [],
      }
      aggregated_data[key] = aggregated_entry
    # Note: the stddev will be recomputed later when the results
    # from each of the multiple iterations are averaged together.
    aggregated_entry['value'].append(perf_value.value)
  return aggregated_data


def _MeanAndStddev(data, precision=4):
  """Computes mean and standard deviation from a list of numbers.

  Args:
    data: A list of numeric values.
    precision: The integer number of decimal places to which to
      round the results.

  Returns:
    A 2-tuple (mean, standard_deviation), in which each value is
      rounded to |precision| decimal places.
  """
  n = len(data)
  if n == 0:
    raise ValueError('Cannot compute mean and stddev of an empty list.')
  if n == 1:
    return round(data[0], precision), 0

  mean = math.fsum(data) / n
  # Divide by n-1 to compute "sample standard deviation".
  variance = math.fsum((elem - mean) ** 2 for elem in data) / (n - 1)
  return round(mean, precision), round(math.sqrt(variance), precision)


def _ComputeAvgStddev(perf_data):
  """Compute average and standard deviations as needed for perf measurements.

  For any perf measurement that exists in multiple iterations (has more than
  one measured value), compute the average and standard deviation for it and
  then store the updated information in the dictionary (in place).

  Args:
    perf_data: A dictionary of measured perf data as computed by
      _AggregateIterations(), except each "value" is now a single value, not
      a list of values.
  """
  for perf in perf_data.itervalues():
    perf['value'], perf['stddev'] = _MeanAndStddev(perf['value'])
  return perf_data


PresentationInfo = collections.namedtuple(
    'PresentationInfo',
    'master_name test_name')


def _GetPresentationInfo(test_name):
  """Get presentation info for |test_name| from config file.

  Args:
    test_name: The test name.

  Returns:
    A PresentationInfo object for this test.
  """
  infos = osutils.ReadFile(_PRESENTATION_CONFIG_FILE)
  infos = json.loads(infos)
  for info in infos:
    if info['test_name'] == test_name:
      try:
        return PresentationInfo(**info)
      except:
        raise PerfUploadingError('No master found for %s' % test_name)

  raise PerfUploadingError('No presentation config found for %s' % test_name)


def _FormatForUpload(perf_data, platform_name, presentation_info, revision=None,
                     cros_version=None, chrome_version=None, test_prefix=None,
                     platform_prefix=None):
  """Formats perf data suitably to upload to the perf dashboard.

  The perf dashboard expects perf data to be uploaded as a
  specially-formatted JSON string.  In particular, the JSON object must be a
  dictionary with key "data", and value being a list of dictionaries where
  each dictionary contains all the information associated with a single
  measured perf value: master name, bot name, test name, perf value, units,
  and build version numbers.

  See also google3/googleclient/chrome/speed/dashboard/add_point.py for the
  server side handler.

  Args:
    platform_name: The string name of the platform.
    perf_data: A dictionary of measured perf data. This is keyed by
      (description, graph name) tuple.
    presentation_info: A PresentationInfo object of the given test.
    revision: The raw X-axis value; normally it represents a VCS repo, but may
      be any monotonic increasing value integer.
    cros_version: A string identifying Chrome OS version e.g. '6052.0.0'.
    chrome_version: A string identifying Chrome version e.g. '38.0.2091.2'.
    test_prefix: Arbitrary string to automatically prefix to the test name.
      If None, then 'cbuildbot.' is used to guarantee namespacing.
    platform_prefix: Arbitrary string to automatically prefix to
      |platform_name|. If None, then 'cros-' is used to guarantee namespacing.

  Returns:
    A dictionary containing the formatted information ready to upload
      to the performance dashboard.
  """
  if test_prefix is None:
    test_prefix = _DEFAULT_TEST_PREFIX
  if platform_prefix is None:
    platform_prefix = _DEFAULT_PLATFORM_PREFIX

  dash_entries = []
  for (desc, graph), data in perf_data.iteritems():
    # Each perf metric is named by a path that encodes the test name,
    # a graph name (if specified), and a description.  This must be defined
    # according to rules set by the Chrome team, as implemented in:
    # chromium/tools/build/scripts/slave/results_dashboard.py.
    desc = desc.replace('/', '_')
    test_name = test_prefix + presentation_info.test_name
    test_parts = [test_name, desc]
    if graph:
      test_parts.insert(1, graph)
    test_path = '/'.join(test_parts)

    supp_cols = {'a_default_rev': 'r_cros_version'}
    if data.get('stdio_uri'):
      supp_cols['a_stdio_uri'] = data['stdio_uri']
    if cros_version is not None:
      supp_cols['r_cros_version'] = cros_version
    if chrome_version is not None:
      supp_cols['r_chrome_version'] = chrome_version

    new_dash_entry = {
        'master': presentation_info.master_name,
        'bot': platform_prefix + platform_name,
        'test': test_path,
        'value': data['value'],
        'error': data['stddev'],
        'units': data['units'],
        'higher_is_better': data['higher_is_better'],
        'supplemental_columns': supp_cols,
    }
    if revision is not None:
      new_dash_entry['revision'] = revision

    dash_entries.append(new_dash_entry)

  json_string = json.dumps(dash_entries)
  return {'data': json_string}


def _SendToDashboard(data_obj, dashboard=DASHBOARD_URL):
  """Sends formatted perf data to the perf dashboard.

  Args:
    data_obj: A formatted data object as returned by _FormatForUpload().
    dashboard: The dashboard to upload data to.

  Raises:
    PerfUploadingError if an exception was raised when uploading.
  """
  upload_url = os.path.join(dashboard, 'add_point')
  encoded = urllib.urlencode(data_obj)
  req = urllib2.Request(upload_url, encoded)
  try:
    urllib2.urlopen(req)
  except urllib2.HTTPError as e:
    raise PerfUploadingError('HTTPError: %d %s for JSON %s\n' %
                             (e.code, e.msg, data_obj['data']), e)
  except urllib2.URLError as e:
    raise PerfUploadingError('URLError: %s for JSON %s\n' %
                             (str(e.reason), data_obj['data']), e)
  except httplib.HTTPException as e:
    raise PerfUploadingError(
        'HTTPException for JSON %s\n' % data_obj['data'], e)


def _ComputeRevisionFromVersions(chrome_version, cros_version):
  """Computes the point ID to use, from Chrome and Chrome OS version numbers.

  For ChromeOS row data, data values are associated with both a Chrome
  version number and a ChromeOS version number (unlike for Chrome row data
  that is associated with a single revision number).  This function takes
  both version numbers as input, then computes a single, unique integer ID
  from them, which serves as a 'fake' revision number that can uniquely
  identify each ChromeOS data point, and which will allow ChromeOS data points
  to be sorted by Chrome version number, with ties broken by ChromeOS version
  number.

  To compute the integer ID, we take the portions of each version number that
  serve as the shortest unambiguous names for each (as described here:
  https://dev.chromium.org/developers/version-numbers).  We then force each
  component of each portion to be a fixed width (padded by zeros if needed),
  concatenate all digits together (with those coming from the Chrome version
  number first), and convert the entire string of digits into an integer.
  We ensure that the total number of digits does not exceed that which is
  allowed by AppEngine NDB for an integer (64-bit signed value).

  For example:
    Chrome version: 27.0.1452.2 (shortest unambiguous name: 1452.2)
    ChromeOS version: 27.3906.0.0 (shortest unambiguous name: 3906.0.0)
    concatenated together with padding for fixed-width columns:
        ('01452' + '002') + ('03906' + '000' + '00') = '014520020390600000'
    Final integer ID: 14520020390600000

  Args:
    chrome_version: The Chrome version number as a string.
    cros_version: The ChromeOS version number as a string.

  Returns:
    A unique integer ID associated with the two given version numbers.
  """
  # Number of digits to use from each part of the version string for Chrome
  # and Chrome OS versions when building a point ID out of these two versions.
  chrome_version_col_widths = [0, 0, 5, 3]
  cros_version_col_widths = [0, 5, 3, 2]

  def get_digits_from_version(version_num, column_widths):
    if re.match(_VERSION_REGEXP, version_num):
      computed_string = ''
      version_parts = version_num.split('.')
      for i, version_part in enumerate(version_parts):
        if column_widths[i]:
          computed_string += version_part.zfill(column_widths[i])
      return computed_string
    else:
      return None

  chrome_digits = get_digits_from_version(
      chrome_version, chrome_version_col_widths)
  cros_digits = get_digits_from_version(
      cros_version, cros_version_col_widths)
  if not chrome_digits or not cros_digits:
    return None
  result_digits = chrome_digits + cros_digits
  max_digits = sum(chrome_version_col_widths + cros_version_col_widths)
  if len(result_digits) > max_digits:
    return None
  return int(result_digits)


def _RetryIfServerError(perf_exc):
  """Exception handler to retry an upload if error code is 5xx.

  Args:
    perf_exc: The exception from _SendToDashboard.

  Returns:
    True if the cause of |perf_exc| is HTTP 5xx error.
  """
  return (isinstance(perf_exc.orig_exc, urllib2.HTTPError) and
          perf_exc.orig_exc.code >= 500)


def UploadPerfValues(perf_values, platform_name, test_name, revision=None,
                     cros_version=None, chrome_version=None,
                     dashboard=DASHBOARD_URL, master_name=None,
                     test_prefix=None, platform_prefix=None, dry_run=False):
  """Uploads any perf data associated with a test to the perf dashboard.

  Note: If |revision| is used, then |cros_version| & |chrome_version| are not
  necessary.  Conversely, if |revision| is not used, then |cros_version| and
  |chrome_version| must both be specified.

  Args:
    perf_values: List of PerformanceValue objects.
    platform_name: A string identifying platform e.g. 'x86-release'. 'cros-'
      will be prepended to |platform_name| internally, by _FormatForUpload.
    test_name: A string identifying the test
    revision: The raw X-axis value; normally it represents a VCS repo, but may
      be any monotonic increasing value integer.
    cros_version: A string identifying Chrome OS version e.g. '6052.0.0'.
    chrome_version: A string identifying Chrome version e.g. '38.0.2091.2'.
    dashboard: The dashboard to upload data to.
    master_name: The "master" field to use; by default it is looked up in the
      perf_dashboard_config.json database.
    test_prefix: Arbitrary string to automatically prefix to the test name.
      If None, then 'cbuildbot.' is used to guarantee namespacing.
    platform_prefix: Arbitrary string to automatically prefix to
      |platform_name|. If None, then 'cros-' is used to guarantee namespacing.
    dry_run: Do everything but upload the data to the server.
  """
  if not perf_values:
    return

  # Aggregate values from multiple iterations together.
  perf_data = _AggregateIterations(perf_values)

  # Compute averages and standard deviations as needed for measured perf
  # values that exist in multiple iterations.  Ultimately, we only upload a
  # single measurement (with standard deviation) for every unique measured
  # perf metric.
  _ComputeAvgStddev(perf_data)

  # Format the perf data for the upload, then upload it.
  if revision is None:
    # No "revision" field, calculate one. Chrome and CrOS fields must be given.
    cros_version = chrome_version[:chrome_version.find('.') + 1] + cros_version
    revision = _ComputeRevisionFromVersions(chrome_version, cros_version)
  try:
    if master_name is None:
      presentation_info = _GetPresentationInfo(test_name)
    else:
      presentation_info = PresentationInfo(master_name, test_name)
    formatted_data = _FormatForUpload(perf_data, platform_name,
                                      presentation_info,
                                      revision=revision,
                                      cros_version=cros_version,
                                      chrome_version=chrome_version,
                                      test_prefix=test_prefix,
                                      platform_prefix=platform_prefix)
    if dry_run:
      logging.debug('UploadPerfValues: skipping upload due to dry-run')
    else:
      retry_util.GenericRetry(_RetryIfServerError, 3, _SendToDashboard,
                              formatted_data, dashboard=dashboard)
  except PerfUploadingError:
    logging.exception('Error when uploading perf data to the perf '
                      'dashboard for test %s.', test_name)
    raise
  else:
    logging.info('Successfully uploaded perf data to the perf '
                 'dashboard for test %s.', test_name)
