# -*- coding: utf-8 -*-
# Copyright (c) 2013 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.

"""Module to deal with result cache."""

from __future__ import division
from __future__ import print_function

import collections
import glob
import hashlib
import heapq
import json
import os
import pickle
import re
import tempfile

from cros_utils import command_executer
from cros_utils import misc

from image_checksummer import ImageChecksummer

import results_report
import test_flag

SCRATCH_DIR = os.path.expanduser('~/cros_scratch')
RESULTS_FILE = 'results.txt'
MACHINE_FILE = 'machine.txt'
AUTOTEST_TARBALL = 'autotest.tbz2'
RESULTS_TARBALL = 'results.tbz2'
PERF_RESULTS_FILE = 'perf-results.txt'
CACHE_KEYS_FILE = 'cache_keys.txt'


class Result(object):
  """Class for holding the results of a single test run.

  This class manages what exactly is stored inside the cache without knowing
  what the key of the cache is. For runs with perf, it stores perf.data,
  perf.report, etc. The key generation is handled by the ResultsCache class.
  """

  def __init__(self, logger, label, log_level, machine, cmd_exec=None):
    self.chromeos_root = label.chromeos_root
    self._logger = logger
    self.ce = cmd_exec or command_executer.GetCommandExecuter(
        self._logger, log_level=log_level)
    self.temp_dir = None
    self.label = label
    self.results_dir = None
    self.log_level = log_level
    self.machine = machine
    self.perf_data_files = []
    self.perf_report_files = []
    self.results_file = []
    self.turbostat_log_file = ''
    self.cpustats_log_file = ''
    self.top_log_file = ''
    self.wait_time_log_file = ''
    self.chrome_version = ''
    self.err = None
    self.chroot_results_dir = ''
    self.test_name = ''
    self.keyvals = None
    self.board = None
    self.suite = None
    self.cwp_dso = ''
    self.retval = None
    self.out = None
    self.top_cmds = []

  def GetTopCmds(self):
    """Get the list of top commands consuming CPU on the machine."""
    return self.top_cmds

  def FormatStringTop5(self):
    """Get formatted top5 string.

    Get the formatted string with top5 commands consuming CPU on DUT machine.
    """
    format_list = [
        'Top 5 commands with highest CPU usage:',
        # Header.
        '%20s %9s %6s   %s' % ('COMMAND', 'AVG CPU%', 'COUNT', 'HIGHEST 5'),
        '-' * 50,
    ]
    if self.top_cmds:
      for topcmd in self.top_cmds[:5]:
        print_line = '%20s %9.2f %6s   %s' % (topcmd['cmd'], topcmd['cpu_avg'],
                                              topcmd['count'], topcmd['top5'])
        format_list.append(print_line)
    else:
      format_list.append('[NO DATA FROM THE TOP LOG]')
    format_list.append('-' * 50)
    return '\n'.join(format_list)

  def CopyFilesTo(self, dest_dir, files_to_copy):
    file_index = 0
    for file_to_copy in files_to_copy:
      if not os.path.isdir(dest_dir):
        command = 'mkdir -p %s' % dest_dir
        self.ce.RunCommand(command)
      dest_file = os.path.join(
          dest_dir, ('%s.%s' % (os.path.basename(file_to_copy), file_index)))
      ret = self.ce.CopyFiles(file_to_copy, dest_file, recursive=False)
      if ret:
        raise IOError('Could not copy results file: %s' % file_to_copy)

  def CopyResultsTo(self, dest_dir):
    self.CopyFilesTo(dest_dir, self.results_file)
    self.CopyFilesTo(dest_dir, self.perf_data_files)
    self.CopyFilesTo(dest_dir, self.perf_report_files)
    if self.results_file or self.perf_data_files or self.perf_report_files:
      self._logger.LogOutput('Results files stored in %s.' % dest_dir)

  def CompressResultsTo(self, dest_dir):
    tarball = os.path.join(self.results_dir, RESULTS_TARBALL)
    # Test_that runs hold all output under TEST_NAME_HASHTAG/results/,
    # while tast runs hold output under TEST_NAME/.
    # Both ensure to be unique.
    result_dir_name = self.test_name if self.suite == 'tast' else 'results'
    results_dir = self.FindFilesInResultsDir(
        '-name %s' % result_dir_name).split('\n')[0]

    if not results_dir:
      self._logger.LogOutput(
          'WARNING: No results dir matching %r found' % result_dir_name)
      return

    self.CreateTarball(results_dir, tarball)
    self.CopyFilesTo(dest_dir, [tarball])
    if results_dir:
      self._logger.LogOutput('Results files compressed into %s.' % dest_dir)

  def GetNewKeyvals(self, keyvals_dict):
    # Initialize 'units' dictionary.
    units_dict = {}
    for k in keyvals_dict:
      units_dict[k] = ''
    results_files = self.GetDataMeasurementsFiles()
    for f in results_files:
      # Make sure we can find the results file
      if os.path.exists(f):
        data_filename = f
      else:
        # Otherwise get the base filename and create the correct
        # path for it.
        _, f_base = misc.GetRoot(f)
        data_filename = os.path.join(self.chromeos_root, 'chroot/tmp',
                                     self.temp_dir, f_base)
      if data_filename.find('.json') > 0:
        raw_dict = dict()
        if os.path.exists(data_filename):
          with open(data_filename, 'r') as data_file:
            raw_dict = json.load(data_file)

        if 'charts' in raw_dict:
          raw_dict = raw_dict['charts']
        for k1 in raw_dict:
          field_dict = raw_dict[k1]
          for k2 in field_dict:
            result_dict = field_dict[k2]
            key = k1 + '__' + k2
            if 'value' in result_dict:
              keyvals_dict[key] = result_dict['value']
            elif 'values' in result_dict:
              values = result_dict['values']
              if ('type' in result_dict and
                  result_dict['type'] == 'list_of_scalar_values' and values and
                  values != 'null'):
                keyvals_dict[key] = sum(values) / float(len(values))
              else:
                keyvals_dict[key] = values
            units_dict[key] = result_dict['units']
      else:
        if os.path.exists(data_filename):
          with open(data_filename, 'r') as data_file:
            lines = data_file.readlines()
            for line in lines:
              tmp_dict = json.loads(line)
              graph_name = tmp_dict['graph']
              graph_str = (graph_name + '__') if graph_name else ''
              key = graph_str + tmp_dict['description']
              keyvals_dict[key] = tmp_dict['value']
              units_dict[key] = tmp_dict['units']

    return keyvals_dict, units_dict

  def AppendTelemetryUnits(self, keyvals_dict, units_dict):
    """keyvals_dict is the dict of key-value used to generate Crosperf reports.

    units_dict is a dictionary of the units for the return values in
    keyvals_dict.  We need to associate the units with the return values,
    for Telemetry tests, so that we can include the units in the reports.
    This function takes each value in keyvals_dict, finds the corresponding
    unit in the units_dict, and replaces the old value with a list of the
    old value and the units.  This later gets properly parsed in the
    ResultOrganizer class, for generating the reports.
    """

    results_dict = {}
    for k in keyvals_dict:
      # We don't want these lines in our reports; they add no useful data.
      if not k or k == 'telemetry_Crosperf':
        continue
      val = keyvals_dict[k]
      units = units_dict[k]
      new_val = [val, units]
      results_dict[k] = new_val
    return results_dict

  def GetKeyvals(self):
    results_in_chroot = os.path.join(self.chromeos_root, 'chroot', 'tmp')
    if not self.temp_dir:
      self.temp_dir = tempfile.mkdtemp(dir=results_in_chroot)
      command = 'cp -r {0}/* {1}'.format(self.results_dir, self.temp_dir)
      self.ce.RunCommand(command, print_to_console=False)

    command = ('./generate_test_report --no-color --csv %s' % (os.path.join(
        '/tmp', os.path.basename(self.temp_dir))))
    _, out, _ = self.ce.ChrootRunCommandWOutput(
        self.chromeos_root, command, print_to_console=False)
    keyvals_dict = {}
    tmp_dir_in_chroot = misc.GetInsideChrootPath(self.chromeos_root,
                                                 self.temp_dir)
    for line in out.splitlines():
      tokens = re.split('=|,', line)
      key = tokens[-2]
      if key.startswith(tmp_dir_in_chroot):
        key = key[len(tmp_dir_in_chroot) + 1:]
      value = tokens[-1]
      keyvals_dict[key] = value

    # Check to see if there is a perf_measurements file and get the
    # data from it if so.
    keyvals_dict, units_dict = self.GetNewKeyvals(keyvals_dict)
    if self.suite == 'telemetry_Crosperf':
      # For telemtry_Crosperf results, append the units to the return
      # results, for use in generating the reports.
      keyvals_dict = self.AppendTelemetryUnits(keyvals_dict, units_dict)
    return keyvals_dict

  def GetSamples(self):
    samples = 0
    for perf_data_file in self.perf_data_files:
      chroot_perf_data_file = misc.GetInsideChrootPath(self.chromeos_root,
                                                       perf_data_file)
      perf_path = os.path.join(self.chromeos_root, 'chroot', 'usr/bin/perf')
      perf_file = '/usr/sbin/perf'
      if os.path.exists(perf_path):
        perf_file = '/usr/bin/perf'

      # For each perf.data, we want to collect sample count for specific DSO.
      # We specify exact match for known DSO type, and every sample for `all`.
      exact_match = ''
      if self.cwp_dso == 'all':
        exact_match = '""'
      elif self.cwp_dso == 'chrome':
        exact_match = '" chrome "'
      elif self.cwp_dso == 'kallsyms':
        exact_match = '"[kernel.kallsyms]"'
      else:
        # This will need to be updated once there are more DSO types supported,
        # if user want an exact match for the field they want.
        exact_match = '"%s"' % self.cwp_dso

      command = ('%s report -n -s dso -i %s 2> /dev/null | grep %s' %
                 (perf_file, chroot_perf_data_file, exact_match))
      _, result, _ = self.ce.ChrootRunCommandWOutput(self.chromeos_root,
                                                     command)
      # Accumulate the sample count for all matched fields.
      # Each line looks like this:
      #     45.42%        237210  chrome
      # And we want the second number which is the sample count.
      sample = 0
      try:
        for line in result.split('\n'):
          attr = line.split()
          if len(attr) == 3 and '%' in attr[0]:
            sample += int(attr[1])
      except:
        raise RuntimeError('Cannot parse perf dso result')

      samples += sample
    return [samples, u'samples']

  def GetResultsDir(self):
    if self.suite == 'tast':
      mo = re.search(r'Writing results to (\S+)', self.out)
    else:
      mo = re.search(r'Results placed in (\S+)', self.out)
    if mo:
      result = mo.group(1)
      return result
    raise RuntimeError('Could not find results directory.')

  def FindFilesInResultsDir(self, find_args):
    if not self.results_dir:
      return ''

    command = 'find %s %s' % (self.results_dir, find_args)
    ret, out, _ = self.ce.RunCommandWOutput(command, print_to_console=False)
    if ret:
      raise RuntimeError('Could not run find command!')
    return out

  def GetResultsFile(self):
    if self.suite == 'telemetry_Crosperf':
      return self.FindFilesInResultsDir('-name histograms.json').splitlines()
    return self.FindFilesInResultsDir('-name results-chart.json').splitlines()

  def GetPerfDataFiles(self):
    return self.FindFilesInResultsDir('-name perf.data').splitlines()

  def GetPerfReportFiles(self):
    return self.FindFilesInResultsDir('-name perf.data.report').splitlines()

  def GetDataMeasurementsFiles(self):
    result = self.FindFilesInResultsDir('-name perf_measurements').splitlines()
    if not result:
      if self.suite == 'telemetry_Crosperf':
        result = \
            self.FindFilesInResultsDir('-name histograms.json').splitlines()
      else:
        result = \
            self.FindFilesInResultsDir('-name results-chart.json').splitlines()
    return result

  def GetTurbostatFile(self):
    """Get turbostat log path string."""
    return self.FindFilesInResultsDir('-name turbostat.log').split('\n')[0]

  def GetCpustatsFile(self):
    """Get cpustats log path string."""
    return self.FindFilesInResultsDir('-name cpustats.log').split('\n')[0]

  def GetTopFile(self):
    """Get cpustats log path string."""
    return self.FindFilesInResultsDir('-name top.log').split('\n')[0]

  def GetWaitTimeFile(self):
    """Get wait time log path string."""
    return self.FindFilesInResultsDir('-name wait_time.log').split('\n')[0]

  def _CheckDebugPath(self, option, path):
    relative_path = path[1:]
    out_chroot_path = os.path.join(self.chromeos_root, 'chroot', relative_path)
    if os.path.exists(out_chroot_path):
      if option == 'kallsyms':
        path = os.path.join(path, 'System.map-*')
      return '--' + option + ' ' + path
    else:
      print('** WARNING **: --%s option not applied, %s does not exist' %
            (option, out_chroot_path))
      return ''

  def GeneratePerfReportFiles(self):
    perf_report_files = []
    for perf_data_file in self.perf_data_files:
      # Generate a perf.report and store it side-by-side with the perf.data
      # file.
      chroot_perf_data_file = misc.GetInsideChrootPath(self.chromeos_root,
                                                       perf_data_file)
      perf_report_file = '%s.report' % perf_data_file
      if os.path.exists(perf_report_file):
        raise RuntimeError(
            'Perf report file already exists: %s' % perf_report_file)
      chroot_perf_report_file = misc.GetInsideChrootPath(
          self.chromeos_root, perf_report_file)
      perf_path = os.path.join(self.chromeos_root, 'chroot', 'usr/bin/perf')

      perf_file = '/usr/sbin/perf'
      if os.path.exists(perf_path):
        perf_file = '/usr/bin/perf'

      debug_path = self.label.debug_path

      if debug_path:
        symfs = '--symfs ' + debug_path
        vmlinux = '--vmlinux ' + os.path.join(debug_path, 'boot', 'vmlinux')
        kallsyms = ''
        print('** WARNING **: --kallsyms option not applied, no System.map-* '
              'for downloaded image.')
      else:
        if self.label.image_type != 'local':
          print('** WARNING **: Using local debug info in /build, this may '
                'not match the downloaded image.')
        build_path = os.path.join('/build', self.board)
        symfs = self._CheckDebugPath('symfs', build_path)
        vmlinux_path = os.path.join(build_path, 'usr/lib/debug/boot/vmlinux')
        vmlinux = self._CheckDebugPath('vmlinux', vmlinux_path)
        kallsyms_path = os.path.join(build_path, 'boot')
        kallsyms = self._CheckDebugPath('kallsyms', kallsyms_path)

      command = ('%s report -n %s %s %s -i %s --stdio > %s' %
                 (perf_file, symfs, vmlinux, kallsyms, chroot_perf_data_file,
                  chroot_perf_report_file))
      if self.log_level != 'verbose':
        self._logger.LogOutput('Generating perf report...\nCMD: %s' % command)
      exit_code = self.ce.ChrootRunCommand(self.chromeos_root, command)
      if exit_code == 0:
        if self.log_level != 'verbose':
          self._logger.LogOutput('Perf report generated successfully.')
      else:
        raise RuntimeError(
            'Perf report not generated correctly. CMD: %s' % command)

      # Add a keyval to the dictionary for the events captured.
      perf_report_files.append(
          misc.GetOutsideChrootPath(self.chromeos_root,
                                    chroot_perf_report_file))
    return perf_report_files

  def GatherPerfResults(self):
    report_id = 0
    for perf_report_file in self.perf_report_files:
      with open(perf_report_file, 'r') as f:
        report_contents = f.read()
        for group in re.findall(r'Events: (\S+) (\S+)', report_contents):
          num_events = group[0]
          event_name = group[1]
          key = 'perf_%s_%s' % (report_id, event_name)
          value = str(misc.UnitToNumber(num_events))
          self.keyvals[key] = value

  def PopulateFromRun(self, out, err, retval, test, suite, cwp_dso):
    self.board = self.label.board
    self.out = out
    self.err = err
    self.retval = retval
    self.test_name = test
    self.suite = suite
    self.cwp_dso = cwp_dso
    self.chroot_results_dir = self.GetResultsDir()
    self.results_dir = misc.GetOutsideChrootPath(self.chromeos_root,
                                                 self.chroot_results_dir)
    self.results_file = self.GetResultsFile()
    self.perf_data_files = self.GetPerfDataFiles()
    # Include all perf.report data in table.
    self.perf_report_files = self.GeneratePerfReportFiles()
    self.turbostat_log_file = self.GetTurbostatFile()
    self.cpustats_log_file = self.GetCpustatsFile()
    self.top_log_file = self.GetTopFile()
    self.wait_time_log_file = self.GetWaitTimeFile()
    # TODO(asharif): Do something similar with perf stat.

    # Grab keyvals from the directory.
    self.ProcessResults()

  def ProcessChartResults(self):
    # Open and parse the json results file generated by telemetry/test_that.
    if not self.results_file:
      raise IOError('No results file found.')
    filename = self.results_file[0]
    if not filename.endswith('.json'):
      raise IOError('Attempt to call json on non-json file: %s' % filename)
    if not os.path.exists(filename):
      raise IOError('%s does not exist' % filename)

    keyvals = {}
    with open(filename, 'r') as f:
      raw_dict = json.load(f)
      if 'charts' in raw_dict:
        raw_dict = raw_dict['charts']
      for k, field_dict in raw_dict.items():
        for item in field_dict:
          keyname = k + '__' + item
          value_dict = field_dict[item]
          if 'value' in value_dict:
            result = value_dict['value']
          elif 'values' in value_dict:
            values = value_dict['values']
            if not values:
              continue
            if ('type' in value_dict and
                value_dict['type'] == 'list_of_scalar_values' and
                values != 'null'):
              result = sum(values) / float(len(values))
            else:
              result = values
          else:
            continue
          units = value_dict['units']
          new_value = [result, units]
          keyvals[keyname] = new_value
    return keyvals

  def ProcessTurbostatResults(self):
    """Given turbostat_log_file non-null parse cpu stats from file.

    Returns:
      Dictionary of 'cpufreq', 'cputemp' where each
      includes dictionary 'all': [list_of_values]

    Example of the output of turbostat_log.
    ----------------------
    CPU     Avg_MHz Busy%   Bzy_MHz TSC_MHz IRQ     CoreTmp
    -       329     12.13   2723    2393    10975   77
    0       336     12.41   2715    2393    6328    77
    2       323     11.86   2731    2393    4647    69
    CPU     Avg_MHz Busy%   Bzy_MHz TSC_MHz IRQ     CoreTmp
    -       1940    67.46   2884    2393    39920   83
    0       1827    63.70   2877    2393    21184   83
    """
    cpustats = {}
    read_data = ''
    with open(self.turbostat_log_file) as f:
      read_data = f.readlines()

    if not read_data:
      self._logger.LogOutput('WARNING: Turbostat output file is empty.')
      return {}

    # First line always contains the header.
    stats = read_data[0].split()

    # Mandatory parameters.
    if 'CPU' not in stats:
      self._logger.LogOutput(
          'WARNING: Missing data for CPU# in Turbostat output.')
      return {}
    if 'Bzy_MHz' not in stats:
      self._logger.LogOutput(
          'WARNING: Missing data for Bzy_MHz in Turbostat output.')
      return {}
    cpu_index = stats.index('CPU')
    cpufreq_index = stats.index('Bzy_MHz')
    cpufreq = cpustats.setdefault('cpufreq', {'all': []})

    # Optional parameters.
    cputemp_index = -1
    if 'CoreTmp' in stats:
      cputemp_index = stats.index('CoreTmp')
      cputemp = cpustats.setdefault('cputemp', {'all': []})

    # Parse data starting from the second line ignoring repeating headers.
    for st in read_data[1:]:
      # Data represented by int or float separated by spaces.
      numbers = st.split()
      if not all(word.replace('.', '', 1).isdigit() for word in numbers[1:]):
        # Skip the line if data mismatch.
        continue
      if numbers[cpu_index] != '-':
        # Ignore Core-specific statistics which starts with Core number.
        # Combined statistics for all core has "-" CPU identifier.
        continue

      cpufreq['all'].append(int(numbers[cpufreq_index]))
      if cputemp_index != -1:
        cputemp['all'].append(int(numbers[cputemp_index]))
    return cpustats

  def ProcessTopResults(self):
    """Given self.top_log_file process top log data.

    Returns:
      List of dictionaries with the following keyvals:
       'cmd': command name (string),
       'cpu_avg': average cpu usage (float),
       'count': number of occurrences (int),
       'top5': up to 5 highest cpu usages (descending list of floats)

    Example of the top log:
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     4102 chronos   12  -8 3454472 238300 118188 R  41.8   6.1   0:08.37 chrome
      375 root       0 -20       0      0      0 S   5.9   0.0   0:00.17 kworker
      617 syslog    20   0   25332   8372   7888 S   5.9   0.2   0:00.77 systemd

      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     5745 chronos   20   0 5438580 139328  67988 R 122.8   3.6   0:04.26 chrome
      912 root     -51   0       0      0      0 S   2.0   0.0   0:01.04 irq/cro
      121 root      20   0       0      0      0 S   1.0   0.0   0:00.45 spi5
    """
    all_data = ''
    with open(self.top_log_file) as f:
      all_data = f.read()

    if not all_data:
      self._logger.LogOutput('WARNING: Top log file is empty.')
      return []

    top_line_regex = re.compile(
        r"""
        ^\s*(?P<pid>\d+)\s+         # Group 1: PID
        \S+\s+\S+\s+-?\d+\s+        # Ignore: user, prio, nice
        \d+\s+\d+\s+\d+\s+          # Ignore: virt/res/shared mem
        \S+\s+                      # Ignore: state
        (?P<cpu_use>\d+\.\d+)\s+    # Group 2: CPU usage
        \d+\.\d+\s+\d+:\d+\.\d+\s+  # Ignore: mem usage, time
        (?P<cmd>\S+)$               # Group 3: command
        """, re.VERBOSE)
    # Page represents top log data per one measurement within time interval
    # 'top_interval'.
    # Pages separated by empty line.
    pages = all_data.split('\n\n')
    # Snapshots are structured representation of the pages.
    snapshots = []
    for page in pages:
      if not page:
        continue

      # Snapshot list will contain all processes (command duplicates are
      # allowed).
      snapshot = []
      for line in page.splitlines():
        match = top_line_regex.match(line)
        if match:
          # Top line is valid, collect data.
          process = {
              # NOTE: One command may be represented by multiple processes.
              'cmd': match.group('cmd'),
              'pid': int(match.group('pid')),
              'cpu_use': float(match.group('cpu_use')),
          }

          # Filter out processes with 0 CPU usage and top command.
          if process['cpu_use'] > 0 and process['cmd'] != 'top':
            snapshot.append(process)

      # If page contained meaningful data add snapshot to the list.
      if snapshot:
        snapshots.append(snapshot)

    # Define threshold of CPU usage when Chrome is busy, i.e. benchmark is
    # running.
    # Ideally it should be 100% but it will be hardly reachable with 1 core.
    # Statistics on DUT with 2-6 cores shows that chrome load of 100%, 95% and
    # 90% equally occurs in 72-74% of all top log snapshots.
    # Further decreasing of load threshold leads to a shifting percent of
    # "high load" snapshots which might include snapshots when benchmark is
    # not running.
    # On 1-core DUT 90% chrome cpu load occurs in 55%, 95% in 33% and 100% in 2%
    # of snapshots accordingly.
    CHROME_HIGH_CPU_LOAD = 90
    # Number of snapshots where chrome is heavily used.
    high_load_snapshots = 0
    # Total CPU use per process in ALL active snapshots.
    cmd_total_cpu_use = collections.defaultdict(float)
    # Top CPU usages per command.
    cmd_top5_cpu_use = collections.defaultdict(list)
    # List of Top Commands to be returned.
    topcmds = []

    for snapshot_processes in snapshots:
      # CPU usage per command in one snapshot.
      cmd_cpu_use_per_snapshot = collections.defaultdict(float)
      for process in snapshot_processes:
        cmd = process['cmd']
        cpu_use = process['cpu_use']

        # Collect CPU usage per command.
        cmd_cpu_use_per_snapshot[cmd] += cpu_use

      if cmd_cpu_use_per_snapshot.setdefault('chrome',
                                             0.0) > CHROME_HIGH_CPU_LOAD:
        # Combined CPU usage of "chrome" command exceeds "High load" threshold
        # which means DUT is busy running a benchmark.
        high_load_snapshots += 1
        for cmd, cpu_use in cmd_cpu_use_per_snapshot.items():
          # Update total CPU usage.
          cmd_total_cpu_use[cmd] += cpu_use

          # Add cpu_use into command top cpu usages, sorted in descending order.
          heapq.heappush(cmd_top5_cpu_use[cmd], round(cpu_use, 1))

    for consumer, usage in sorted(
        cmd_total_cpu_use.items(), key=lambda x: x[1], reverse=True):
      # Iterate through commands by descending order of total CPU usage.
      topcmd = {
          'cmd': consumer,
          'cpu_avg': usage / high_load_snapshots,
          'count': len(cmd_top5_cpu_use[consumer]),
          'top5': heapq.nlargest(5, cmd_top5_cpu_use[consumer]),
      }
      topcmds.append(topcmd)

    return topcmds

  def ProcessCpustatsResults(self):
    """Given cpustats_log_file non-null parse cpu data from file.

    Returns:
      Dictionary of 'cpufreq', 'cputemp' where each
      includes dictionary of parameter: [list_of_values]

    Example of cpustats.log output.
    ----------------------
    /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq 1512000
    /sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq 2016000
    little-cpu 41234
    big-cpu 51234

    If cores share the same policy their frequencies may always match
    on some devices.
    To make report concise we should eliminate redundancy in the output.
    Function removes cpuN data if it duplicates data from other cores.
    """

    cpustats = {}
    read_data = ''
    with open(self.cpustats_log_file) as f:
      read_data = f.readlines()

    if not read_data:
      self._logger.LogOutput('WARNING: Cpustats output file is empty.')
      return {}

    cpufreq_regex = re.compile(r'^[/\S]+/(cpu\d+)/[/\S]+\s+(\d+)$')
    cputemp_regex = re.compile(r'^([^/\s]+)\s+(\d+)$')

    for st in read_data:
      match = cpufreq_regex.match(st)
      if match:
        cpu = match.group(1)
        # CPU frequency comes in kHz.
        freq_khz = int(match.group(2))
        freq_mhz = freq_khz / 1000
        # cpufreq represents a dictionary with CPU frequency-related
        # data from cpustats.log.
        cpufreq = cpustats.setdefault('cpufreq', {})
        cpu_n_freq = cpufreq.setdefault(cpu, [])
        cpu_n_freq.append(freq_mhz)
      else:
        match = cputemp_regex.match(st)
        if match:
          therm_type = match.group(1)
          # The value is int, uCelsius unit.
          temp_uc = float(match.group(2))
          # Round to XX.X float.
          temp_c = round(temp_uc / 1000, 1)
          # cputemp represents a dictionary with temperature measurements
          # from cpustats.log.
          cputemp = cpustats.setdefault('cputemp', {})
          therm_type = cputemp.setdefault(therm_type, [])
          therm_type.append(temp_c)

    # Remove duplicate statistics from cpustats.
    pruned_stats = {}
    for cpukey, cpuparam in cpustats.items():
      # Copy 'cpufreq' and 'cputemp'.
      pruned_params = pruned_stats.setdefault(cpukey, {})
      for paramkey, paramvalue in sorted(cpuparam.items()):
        # paramvalue is list of all measured data.
        if paramvalue not in pruned_params.values():
          pruned_params[paramkey] = paramvalue

    return pruned_stats

  def ProcessHistogramsResults(self):
    # Open and parse the json results file generated by telemetry/test_that.
    if not self.results_file:
      raise IOError('No results file found.')
    filename = self.results_file[0]
    if not filename.endswith('.json'):
      raise IOError('Attempt to call json on non-json file: %s' % filename)
    if not os.path.exists(filename):
      raise IOError('%s does not exist' % filename)

    keyvals = {}
    with open(filename) as f:
      histograms = json.load(f)
      value_map = {}
      # Gets generic set values.
      for obj in histograms:
        if 'type' in obj and obj['type'] == 'GenericSet':
          value_map[obj['guid']] = obj['values']

      for obj in histograms:
        if 'name' not in obj or 'sampleValues' not in obj:
          continue
        metric_name = obj['name']
        vals = obj['sampleValues']
        if isinstance(vals, list):
          # Remove None elements from the list
          vals = [val for val in vals if val is not None]
          if vals:
            result = float(sum(vals)) / len(vals)
          else:
            result = 0
        else:
          result = vals
        unit = obj['unit']
        diagnostics = obj['diagnostics']
        # for summaries of benchmarks
        key = metric_name
        if key not in keyvals:
          keyvals[key] = [[result], unit]
        else:
          keyvals[key][0].append(result)
        # TODO: do we need summaries of stories?
        # for summaries of story tags
        if 'storyTags' in diagnostics:
          guid = diagnostics['storyTags']
          if guid not in value_map:
            raise RuntimeError('Unrecognized storyTags in %s ' % (obj))
          for story_tag in value_map[guid]:
            key = metric_name + '__' + story_tag
            if key not in keyvals:
              keyvals[key] = [[result], unit]
            else:
              keyvals[key][0].append(result)
    # calculate summary
    for key in keyvals:
      vals = keyvals[key][0]
      unit = keyvals[key][1]
      result = float(sum(vals)) / len(vals)
      keyvals[key] = [result, unit]
    return keyvals

  def ProcessResults(self, use_cache=False):
    # Note that this function doesn't know anything about whether there is a
    # cache hit or miss. It should process results agnostic of the cache hit
    # state.
    if (self.results_file and self.suite == 'telemetry_Crosperf' and
        'histograms.json' in self.results_file[0]):
      self.keyvals = self.ProcessHistogramsResults()
    elif (self.results_file and self.suite != 'telemetry_Crosperf' and
          'results-chart.json' in self.results_file[0]):
      self.keyvals = self.ProcessChartResults()
    else:
      if not use_cache:
        print('\n ** WARNING **: Had to use deprecated output-method to '
              'collect results.\n')
      self.keyvals = self.GetKeyvals()
    self.keyvals['retval'] = self.retval
    # If we are in CWP approximation mode, we want to collect DSO samples
    # for each perf.data file
    if self.cwp_dso and self.retval == 0:
      self.keyvals['samples'] = self.GetSamples()
      # If the samples count collected from perf file is 0, we will treat
      # it as a failed run.
      if self.keyvals['samples'][0] == 0:
        del self.keyvals['samples']
        self.keyvals['retval'] = 1
    # Generate report from all perf.data files.
    # Now parse all perf report files and include them in keyvals.
    self.GatherPerfResults()

    cpustats = {}
    # Turbostat output has higher priority of processing.
    if self.turbostat_log_file:
      cpustats = self.ProcessTurbostatResults()
    # Process cpustats output only if turbostat has no data.
    if not cpustats and self.cpustats_log_file:
      cpustats = self.ProcessCpustatsResults()
    if self.top_log_file:
      self.top_cmds = self.ProcessTopResults()
    if self.wait_time_log_file:
      with open(self.wait_time_log_file) as f:
        wait_time = f.readline().strip()
        try:
          wait_time = float(wait_time)
        except ValueError:
          raise ValueError('Wait time in log file is not a number.')
      # This is for accumulating wait time for telemtry_Crosperf runs only,
      # for test_that runs, please refer to suite_runner.
      self.machine.AddCooldownWaitTime(wait_time)

    for param_key, param in cpustats.items():
      for param_type, param_values in param.items():
        val_avg = sum(param_values) / len(param_values)
        val_min = min(param_values)
        val_max = max(param_values)
        # Average data is always included.
        self.keyvals['_'.join([param_key, param_type, 'avg'])] = val_avg
        # Insert min/max results only if they deviate
        # from average.
        if val_min != val_avg:
          self.keyvals['_'.join([param_key, param_type, 'min'])] = val_min
        if val_max != val_avg:
          self.keyvals['_'.join([param_key, param_type, 'max'])] = val_max

  def GetChromeVersionFromCache(self, cache_dir):
    # Read chrome_version from keys file, if present.
    chrome_version = ''
    keys_file = os.path.join(cache_dir, CACHE_KEYS_FILE)
    if os.path.exists(keys_file):
      with open(keys_file, 'r') as f:
        lines = f.readlines()
        for l in lines:
          if l.startswith('Google Chrome '):
            chrome_version = l
            if chrome_version.endswith('\n'):
              chrome_version = chrome_version[:-1]
            break
    return chrome_version

  def PopulateFromCacheDir(self, cache_dir, test, suite, cwp_dso):
    self.test_name = test
    self.suite = suite
    self.cwp_dso = cwp_dso
    # Read in everything from the cache directory.
    with open(os.path.join(cache_dir, RESULTS_FILE), 'rb') as f:
      self.out = pickle.load(f)
      self.err = pickle.load(f)
      self.retval = pickle.load(f)

    # Untar the tarball to a temporary directory
    self.temp_dir = tempfile.mkdtemp(
        dir=os.path.join(self.chromeos_root, 'chroot', 'tmp'))

    command = ('cd %s && tar xf %s' %
               (self.temp_dir, os.path.join(cache_dir, AUTOTEST_TARBALL)))
    ret = self.ce.RunCommand(command, print_to_console=False)
    if ret:
      raise RuntimeError('Could not untar cached tarball')
    self.results_dir = self.temp_dir
    self.results_file = self.GetDataMeasurementsFiles()
    self.perf_data_files = self.GetPerfDataFiles()
    self.perf_report_files = self.GetPerfReportFiles()
    self.chrome_version = self.GetChromeVersionFromCache(cache_dir)
    self.ProcessResults(use_cache=True)

  def CleanUp(self, rm_chroot_tmp):
    if rm_chroot_tmp and self.results_dir:
      dirname, basename = misc.GetRoot(self.results_dir)
      if basename.find('test_that_results_') != -1:
        command = 'rm -rf %s' % self.results_dir
      else:
        command = 'rm -rf %s' % dirname
      self.ce.RunCommand(command)
    if self.temp_dir:
      command = 'rm -rf %s' % self.temp_dir
      self.ce.RunCommand(command)

  def CreateTarball(self, results_dir, tarball):
    if not results_dir.strip():
      raise ValueError(
          'Refusing to `tar` an empty results_dir: %r' % results_dir)

    ret = self.ce.RunCommand('cd %s && '
                             'tar '
                             '--exclude=var/spool '
                             '--exclude=var/log '
                             '-cjf %s .' % (results_dir, tarball))
    if ret:
      raise RuntimeError("Couldn't compress test output directory.")

  def StoreToCacheDir(self, cache_dir, machine_manager, key_list):
    # Create the dir if it doesn't exist.
    temp_dir = tempfile.mkdtemp()

    # Store to the temp directory.
    with open(os.path.join(temp_dir, RESULTS_FILE), 'wb') as f:
      pickle.dump(self.out, f)
      pickle.dump(self.err, f)
      pickle.dump(self.retval, f)

    if not test_flag.GetTestMode():
      with open(os.path.join(temp_dir, CACHE_KEYS_FILE), 'w') as f:
        f.write('%s\n' % self.label.name)
        f.write('%s\n' % self.label.chrome_version)
        f.write('%s\n' % self.machine.checksum_string)
        for k in key_list:
          f.write(k)
          f.write('\n')

    if self.results_dir:
      tarball = os.path.join(temp_dir, AUTOTEST_TARBALL)
      self.CreateTarball(self.results_dir, tarball)

    # Store machine info.
    # TODO(asharif): Make machine_manager a singleton, and don't pass it into
    # this function.
    with open(os.path.join(temp_dir, MACHINE_FILE), 'w') as f:
      f.write(machine_manager.machine_checksum_string[self.label.name])

    if os.path.exists(cache_dir):
      command = 'rm -rf {0}'.format(cache_dir)
      self.ce.RunCommand(command)

    command = 'mkdir -p {0} && '.format(os.path.dirname(cache_dir))
    command += 'chmod g+x {0} && '.format(temp_dir)
    command += 'mv {0} {1}'.format(temp_dir, cache_dir)
    ret = self.ce.RunCommand(command)
    if ret:
      command = 'rm -rf {0}'.format(temp_dir)
      self.ce.RunCommand(command)
      raise RuntimeError(
          'Could not move dir %s to dir %s' % (temp_dir, cache_dir))

  @classmethod
  def CreateFromRun(cls,
                    logger,
                    log_level,
                    label,
                    machine,
                    out,
                    err,
                    retval,
                    test,
                    suite='telemetry_Crosperf',
                    cwp_dso=''):
    if suite == 'telemetry':
      result = TelemetryResult(logger, label, log_level, machine)
    else:
      result = cls(logger, label, log_level, machine)
    result.PopulateFromRun(out, err, retval, test, suite, cwp_dso)
    return result

  @classmethod
  def CreateFromCacheHit(cls,
                         logger,
                         log_level,
                         label,
                         machine,
                         cache_dir,
                         test,
                         suite='telemetry_Crosperf',
                         cwp_dso=''):
    if suite == 'telemetry':
      result = TelemetryResult(logger, label, log_level, machine)
    else:
      result = cls(logger, label, log_level, machine)
    try:
      result.PopulateFromCacheDir(cache_dir, test, suite, cwp_dso)

    except RuntimeError as e:
      logger.LogError('Exception while using cache: %s' % e)
      return None
    return result


class TelemetryResult(Result):
  """Class to hold the results of a single Telemetry run."""

  def PopulateFromRun(self, out, err, retval, test, suite, cwp_dso):
    self.out = out
    self.err = err
    self.retval = retval

    self.ProcessResults()

  # pylint: disable=arguments-differ
  def ProcessResults(self):
    # The output is:
    # url,average_commit_time (ms),...
    # www.google.com,33.4,21.2,...
    # We need to convert to this format:
    # {"www.google.com:average_commit_time (ms)": "33.4",
    #  "www.google.com:...": "21.2"}
    # Added note:  Occasionally the output comes back
    # with "JSON.stringify(window.automation.GetResults())" on
    # the first line, and then the rest of the output as
    # described above.

    lines = self.out.splitlines()
    self.keyvals = {}

    if lines:
      if lines[0].startswith('JSON.stringify'):
        lines = lines[1:]

    if not lines:
      return
    labels = lines[0].split(',')
    for line in lines[1:]:
      fields = line.split(',')
      if len(fields) != len(labels):
        continue
      for i in range(1, len(labels)):
        key = '%s %s' % (fields[0], labels[i])
        value = fields[i]
        self.keyvals[key] = value
    self.keyvals['retval'] = self.retval

  def PopulateFromCacheDir(self, cache_dir, test, suite, cwp_dso):
    self.test_name = test
    self.suite = suite
    self.cwp_dso = cwp_dso
    with open(os.path.join(cache_dir, RESULTS_FILE), 'rb') as f:
      self.out = pickle.load(f)
      self.err = pickle.load(f)
      self.retval = pickle.load(f)

    self.chrome_version = \
        super(TelemetryResult, self).GetChromeVersionFromCache(cache_dir)
    self.ProcessResults()


class CacheConditions(object):
  """Various Cache condition values, for export."""

  # Cache hit only if the result file exists.
  CACHE_FILE_EXISTS = 0

  # Cache hit if the checksum of cpuinfo and totalmem of
  # the cached result and the new run match.
  MACHINES_MATCH = 1

  # Cache hit if the image checksum of the cached result and the new run match.
  CHECKSUMS_MATCH = 2

  # Cache hit only if the cached result was successful
  RUN_SUCCEEDED = 3

  # Never a cache hit.
  FALSE = 4

  # Cache hit if the image path matches the cached image path.
  IMAGE_PATH_MATCH = 5

  # Cache hit if the uuid of hard disk mataches the cached one

  SAME_MACHINE_MATCH = 6


class ResultsCache(object):
  """Class to handle the cache for storing/retrieving test run results.

  This class manages the key of the cached runs without worrying about what
  is exactly stored (value). The value generation is handled by the Results
  class.
  """
  CACHE_VERSION = 6

  def __init__(self):
    # Proper initialization happens in the Init function below.
    self.chromeos_image = None
    self.chromeos_root = None
    self.test_name = None
    self.iteration = None
    self.test_args = None
    self.profiler_args = None
    self.board = None
    self.cache_conditions = None
    self.machine_manager = None
    self.machine = None
    self._logger = None
    self.ce = None
    self.label = None
    self.share_cache = None
    self.suite = None
    self.log_level = None
    self.show_all = None
    self.run_local = None
    self.cwp_dso = None

  def Init(self, chromeos_image, chromeos_root, test_name, iteration, test_args,
           profiler_args, machine_manager, machine, board, cache_conditions,
           logger_to_use, log_level, label, share_cache, suite,
           show_all_results, run_local, cwp_dso):
    self.chromeos_image = chromeos_image
    self.chromeos_root = chromeos_root
    self.test_name = test_name
    self.iteration = iteration
    self.test_args = test_args
    self.profiler_args = profiler_args
    self.board = board
    self.cache_conditions = cache_conditions
    self.machine_manager = machine_manager
    self.machine = machine
    self._logger = logger_to_use
    self.ce = command_executer.GetCommandExecuter(
        self._logger, log_level=log_level)
    self.label = label
    self.share_cache = share_cache
    self.suite = suite
    self.log_level = log_level
    self.show_all = show_all_results
    self.run_local = run_local
    self.cwp_dso = cwp_dso

  def GetCacheDirForRead(self):
    matching_dirs = []
    for glob_path in self.FormCacheDir(self.GetCacheKeyList(True)):
      matching_dirs += glob.glob(glob_path)

    if matching_dirs:
      # Cache file found.
      return matching_dirs[0]
    return None

  def GetCacheDirForWrite(self, get_keylist=False):
    cache_path = self.FormCacheDir(self.GetCacheKeyList(False))[0]
    if get_keylist:
      args_str = '%s_%s_%s' % (self.test_args, self.profiler_args,
                               self.run_local)
      version, image = results_report.ParseChromeosImage(
          self.label.chromeos_image)
      keylist = [
          version, image, self.label.board, self.machine.name, self.test_name,
          str(self.iteration), args_str
      ]
      return cache_path, keylist
    return cache_path

  def FormCacheDir(self, list_of_strings):
    cache_key = ' '.join(list_of_strings)
    cache_dir = misc.GetFilenameFromString(cache_key)
    if self.label.cache_dir:
      cache_home = os.path.abspath(os.path.expanduser(self.label.cache_dir))
      cache_path = [os.path.join(cache_home, cache_dir)]
    else:
      cache_path = [os.path.join(SCRATCH_DIR, cache_dir)]

    if self.share_cache:
      for path in [x.strip() for x in self.share_cache.split(',')]:
        if os.path.exists(path):
          cache_path.append(os.path.join(path, cache_dir))
        else:
          self._logger.LogFatal('Unable to find shared cache: %s' % path)

    return cache_path

  def GetCacheKeyList(self, read):
    if read and CacheConditions.MACHINES_MATCH not in self.cache_conditions:
      machine_checksum = '*'
    else:
      machine_checksum = self.machine_manager.machine_checksum[self.label.name]
    if read and CacheConditions.CHECKSUMS_MATCH not in self.cache_conditions:
      checksum = '*'
    elif self.label.image_type == 'trybot':
      checksum = hashlib.md5(
          self.label.chromeos_image.encode('utf-8')).hexdigest()
    elif self.label.image_type == 'official':
      checksum = '*'
    else:
      checksum = ImageChecksummer().Checksum(self.label, self.log_level)

    if read and CacheConditions.IMAGE_PATH_MATCH not in self.cache_conditions:
      image_path_checksum = '*'
    else:
      image_path_checksum = hashlib.md5(
          self.chromeos_image.encode('utf-8')).hexdigest()

    machine_id_checksum = ''
    if read and CacheConditions.SAME_MACHINE_MATCH not in self.cache_conditions:
      machine_id_checksum = '*'
    else:
      if self.machine and self.machine.name in self.label.remote:
        machine_id_checksum = self.machine.machine_id_checksum
      else:
        for machine in self.machine_manager.GetMachines(self.label):
          if machine.name == self.label.remote[0]:
            machine_id_checksum = machine.machine_id_checksum
            break

    temp_test_args = '%s %s %s' % (self.test_args, self.profiler_args,
                                   self.run_local)
    test_args_checksum = hashlib.md5(temp_test_args.encode('utf-8')).hexdigest()
    return (image_path_checksum, self.test_name, str(self.iteration),
            test_args_checksum, checksum, machine_checksum, machine_id_checksum,
            str(self.CACHE_VERSION))

  def ReadResult(self):
    if CacheConditions.FALSE in self.cache_conditions:
      cache_dir = self.GetCacheDirForWrite()
      command = 'rm -rf %s' % (cache_dir,)
      self.ce.RunCommand(command)
      return None
    cache_dir = self.GetCacheDirForRead()

    if not cache_dir:
      return None

    if not os.path.isdir(cache_dir):
      return None

    if self.log_level == 'verbose':
      self._logger.LogOutput('Trying to read from cache dir: %s' % cache_dir)
    result = Result.CreateFromCacheHit(self._logger, self.log_level, self.label,
                                       self.machine, cache_dir, self.test_name,
                                       self.suite, self.cwp_dso)
    if not result:
      return None

    if (result.retval == 0 or
        CacheConditions.RUN_SUCCEEDED not in self.cache_conditions):
      return result

    return None

  def StoreResult(self, result):
    cache_dir, keylist = self.GetCacheDirForWrite(get_keylist=True)
    result.StoreToCacheDir(cache_dir, self.machine_manager, keylist)


class MockResultsCache(ResultsCache):
  """Class for mock testing, corresponding to ResultsCache class."""

  # FIXME: pylint complains about this mock init method, we should probably
  # replace all Mock classes in Crosperf with simple Mock.mock().
  # pylint: disable=arguments-differ
  def Init(self, *args):
    pass

  def ReadResult(self):
    return None

  def StoreResult(self, result):
    pass


class MockResult(Result):
  """Class for mock testing, corresponding to Result class."""

  def PopulateFromRun(self, out, err, retval, test, suite, cwp_dso):
    self.out = out
    self.err = err
    self.retval = retval
