# 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.
"""A module to handle the report format."""
from __future__ import print_function

import datetime
import functools
import itertools
import json
import os
import re

from cros_utils.tabulator import AmeanResult
from cros_utils.tabulator import Cell
from cros_utils.tabulator import CoeffVarFormat
from cros_utils.tabulator import CoeffVarResult
from cros_utils.tabulator import Column
from cros_utils.tabulator import CPUCyclesTableGenerator
from cros_utils.tabulator import Format
from cros_utils.tabulator import IterationResult
from cros_utils.tabulator import GmeanRatioResult
from cros_utils.tabulator import LiteralResult
from cros_utils.tabulator import MaxResult
from cros_utils.tabulator import MinResult
from cros_utils.tabulator import PValueFormat
from cros_utils.tabulator import PValueResult
from cros_utils.tabulator import RatioFormat
from cros_utils.tabulator import RawResult
from cros_utils.tabulator import StdResult
from cros_utils.tabulator import TableFormatter
from cros_utils.tabulator import TableGenerator
from cros_utils.tabulator import TablePrinter
from update_telemetry_defaults import TelemetryDefaults

from column_chart import ColumnChart
from results_organizer import OrganizeResults

import results_report_templates as templates


def ParseChromeosImage(chromeos_image):
  """Parse the chromeos_image string for the image and version.

  The chromeos_image string will probably be in one of two formats:
  1: <path-to-chroot>/src/build/images/<board>/<ChromeOS-version>.<datetime>/ \
     chromiumos_test_image.bin
  2: <path-to-chroot>/chroot/tmp/<buildbot-build>/<ChromeOS-version>/ \
      chromiumos_test_image.bin

  We parse these strings to find the 'chromeos_version' to store in the
  json archive (without the .datatime bit in the first case); and also
  the 'chromeos_image', which would be all of the first case, but only the
  part after '/chroot/tmp' in the second case.

  Args:
      chromeos_image: string containing the path to the chromeos_image that
      crosperf used for the test.

  Returns:
      version, image: The results of parsing the input string, as explained
      above.
  """
  # Find the Chromeos Version, e.g. R45-2345.0.0.....
  # chromeos_image should have been something like:
  # <path>/<board-trybot-release>/<chromeos-version>/chromiumos_test_image.bin"
  if chromeos_image.endswith('/chromiumos_test_image.bin'):
    full_version = chromeos_image.split('/')[-2]
    # Strip the date and time off of local builds (which have the format
    # "R43-2345.0.0.date-and-time").
    version, _ = os.path.splitext(full_version)
  else:
    version = ''

  # Find the chromeos image.  If it's somewhere in .../chroot/tmp/..., then
  # it's an official image that got downloaded, so chop off the download path
  # to make the official image name more clear.
  official_image_path = '/chroot/tmp'
  if official_image_path in chromeos_image:
    image = chromeos_image.split(official_image_path, 1)[1]
  else:
    image = chromeos_image
  return version, image


def _AppendUntilLengthIs(gen, the_list, target_len):
  """Appends to `list` until `list` is `target_len` elements long.

  Uses `gen` to generate elements.
  """
  the_list.extend(gen() for _ in xrange(target_len - len(the_list)))
  return the_list


def _FilterPerfReport(event_threshold, report):
  """Filters out entries with `< event_threshold` percent in a perf report."""

  def filter_dict(m):
    return {
        fn_name: pct
        for fn_name, pct in m.iteritems() if pct >= event_threshold
    }

  return {event: filter_dict(m) for event, m in report.iteritems()}


class _PerfTable(object):
  """Generates dicts from a perf table.

  Dicts look like:
  {'benchmark_name': {'perf_event_name': [LabelData]}}
  where LabelData is a list of perf dicts, each perf dict coming from the same
  label.
  Each perf dict looks like {'function_name': 0.10, ...} (where 0.10 is the
  percentage of time spent in function_name).
  """

  def __init__(self,
               benchmark_names_and_iterations,
               label_names,
               read_perf_report,
               event_threshold=None):
    """Constructor.

    read_perf_report is a function that takes a label name, benchmark name, and
    benchmark iteration, and returns a dictionary describing the perf output for
    that given run.
    """
    self.event_threshold = event_threshold
    self._label_indices = {name: i for i, name in enumerate(label_names)}
    self.perf_data = {}
    for label in label_names:
      for bench_name, bench_iterations in benchmark_names_and_iterations:
        for i in xrange(bench_iterations):
          report = read_perf_report(label, bench_name, i)
          self._ProcessPerfReport(report, label, bench_name, i)

  def _ProcessPerfReport(self, perf_report, label, benchmark_name, iteration):
    """Add the data from one run to the dict."""
    perf_of_run = perf_report
    if self.event_threshold is not None:
      perf_of_run = _FilterPerfReport(self.event_threshold, perf_report)
    if benchmark_name not in self.perf_data:
      self.perf_data[benchmark_name] = {event: [] for event in perf_of_run}
    ben_data = self.perf_data[benchmark_name]
    label_index = self._label_indices[label]
    for event in ben_data:
      _AppendUntilLengthIs(list, ben_data[event], label_index + 1)
      data_for_label = ben_data[event][label_index]
      _AppendUntilLengthIs(dict, data_for_label, iteration + 1)
      data_for_label[iteration] = perf_of_run[event] if perf_of_run else {}


def _GetResultsTableHeader(ben_name, iterations):
  benchmark_info = ('Benchmark:  {0};  Iterations: {1}'.format(
      ben_name, iterations))
  cell = Cell()
  cell.string_value = benchmark_info
  cell.header = True
  return [[cell]]

def _GetDSOHeader(cwp_dso):
  info = 'CWP_DSO: %s' % cwp_dso
  cell = Cell()
  cell.string_value = info
  cell.header = False
  return [[cell]]

def _ParseColumn(columns, iteration):
  new_column = []
  for column in columns:
    if column.result.__class__.__name__ != 'RawResult':
      new_column.append(column)
    else:
      new_column.extend(
          Column(LiteralResult(i), Format(), str(i + 1))
          for i in xrange(iteration))
  return new_column


def _GetTables(benchmark_results, columns, table_type):
  iter_counts = benchmark_results.iter_counts
  result = benchmark_results.run_keyvals
  tables = []
  for bench_name, runs in result.iteritems():
    iterations = iter_counts[bench_name]
    ben_table = _GetResultsTableHeader(bench_name, iterations)

    all_runs_empty = all(not dict for label in runs for dict in label)
    if all_runs_empty:
      cell = Cell()
      cell.string_value = ('This benchmark contains no result.'
                           ' Is the benchmark name valid?')
      cell_table = [[cell]]
    else:
      table = TableGenerator(runs, benchmark_results.label_names).GetTable()
      parsed_columns = _ParseColumn(columns, iterations)
      tf = TableFormatter(table, parsed_columns)
      cell_table = tf.GetCellTable(table_type)
    tables.append(ben_table)
    tables.append(cell_table)
  return tables


def _GetPerfTables(benchmark_results, columns, table_type):
  p_table = _PerfTable(benchmark_results.benchmark_names_and_iterations,
                       benchmark_results.label_names,
                       benchmark_results.read_perf_report)

  tables = []
  for benchmark in p_table.perf_data:
    iterations = benchmark_results.iter_counts[benchmark]
    ben_table = _GetResultsTableHeader(benchmark, iterations)
    tables.append(ben_table)
    benchmark_data = p_table.perf_data[benchmark]
    table = []
    for event in benchmark_data:
      tg = TableGenerator(
          benchmark_data[event],
          benchmark_results.label_names,
          sort=TableGenerator.SORT_BY_VALUES_DESC)
      table = tg.GetTable(ResultsReport.PERF_ROWS)
      parsed_columns = _ParseColumn(columns, iterations)
      tf = TableFormatter(table, parsed_columns)
      tf.GenerateCellTable(table_type)
      tf.AddColumnName()
      tf.AddLabelName()
      tf.AddHeader(str(event))
      table = tf.GetCellTable(table_type, headers=False)
      tables.append(table)
  return tables

def _GetCPUTables(benchmark_results, columns, table_type):
  tables = []
  dso_header_table = _GetDSOHeader(benchmark_results.cwp_dso)
  tables.append(dso_header_table)
  (table, new_keyvals, iter_counts) = CPUCyclesTableGenerator(
                                        benchmark_results.run_keyvals,
                                        benchmark_results.label_names,
                                        benchmark_results.iter_counts,
                                        benchmark_results.weights).GetTable()
  parsed_columns = _ParseColumn(columns, 1)
  tf = TableFormatter(table, parsed_columns, cpu_table=True)
  cell_table = tf.GetCellTable(table_type)
  tables.append(cell_table)
  return (tables, new_keyvals, iter_counts)

class ResultsReport(object):
  """Class to handle the report format."""
  MAX_COLOR_CODE = 255
  PERF_ROWS = 5

  def __init__(self, results):
    self.benchmark_results = results

  def _GetTablesWithColumns(self, columns, table_type, summary_type):
    if summary_type == 'perf':
      get_tables = _GetPerfTables
    elif summary_type == 'cpu':
      get_tables = _GetCPUTables
    else:
      get_tables = _GetTables
    ret = get_tables(self.benchmark_results, columns, table_type)
    # If we are generating a CPU summary table, the return value of get_tables
    # will be a tuple, and we will update the benchmark_results for composite
    # benchmark so that full table can use it.
    if isinstance(ret, tuple):
      self.benchmark_results.run_keyvals = ret[1]
      self.benchmark_results.iter_counts = ret[2]
      ret = ret[0]
    return ret

  def GetFullTables(self, perf=False):
    columns = [
        Column(RawResult(), Format()), Column(MinResult(), Format()), Column(
            MaxResult(), Format()), Column(AmeanResult(), Format()), Column(
                StdResult(), Format(), 'StdDev'),
        Column(CoeffVarResult(), CoeffVarFormat(), 'StdDev/Mean'), Column(
            GmeanRatioResult(), RatioFormat(), 'GmeanSpeedup'), Column(
                PValueResult(), PValueFormat(), 'p-value')
    ]
    return self._GetTablesWithColumns(columns, 'full', perf)

  def GetSummaryTables(self, summary_type=''):
    if summary_type == 'cpu':
      columns = [Column(IterationResult(), Format(), 'Iterations [Pass:Fail]'),
                 Column(AmeanResult(), Format(), 'Weighted CPU-cycles Amean'),
                 Column(StdResult(), Format(), 'StdDev'),
                 Column(CoeffVarResult(), CoeffVarFormat(), 'StdDev/Mean'),
                 Column(GmeanRatioResult(), RatioFormat(), 'GmeanSpeedup'),
                 Column(PValueResult(), PValueFormat(), 'p-value')]
    else:
      columns = [Column(AmeanResult(), Format()),
                 Column(StdResult(), Format(), 'StdDev'),
                 Column(CoeffVarResult(), CoeffVarFormat(), 'StdDev/Mean'),
                 Column(GmeanRatioResult(), RatioFormat(), 'GmeanSpeedup'),
                 Column(PValueResult(), PValueFormat(), 'p-value')]
    return self._GetTablesWithColumns(columns, 'summary', summary_type)


def _PrintTable(tables, out_to):
  # tables may be None.
  if not tables:
    return ''

  if out_to == 'HTML':
    out_type = TablePrinter.HTML
  elif out_to == 'PLAIN':
    out_type = TablePrinter.PLAIN
  elif out_to == 'CONSOLE':
    out_type = TablePrinter.CONSOLE
  elif out_to == 'TSV':
    out_type = TablePrinter.TSV
  elif out_to == 'EMAIL':
    out_type = TablePrinter.EMAIL
  else:
    raise ValueError('Invalid out_to value: %s' % (out_to,))

  printers = (TablePrinter(table, out_type) for table in tables)
  return ''.join(printer.Print() for printer in printers)


class TextResultsReport(ResultsReport):
  """Class to generate text result report."""

  H1_STR = '==========================================='
  H2_STR = '-------------------------------------------'

  def __init__(self, results, email=False, experiment=None):
    super(TextResultsReport, self).__init__(results)
    self.email = email
    self.experiment = experiment

  @staticmethod
  def _MakeTitle(title):
    header_line = TextResultsReport.H1_STR
    # '' at the end gives one newline.
    return '\n'.join([header_line, title, header_line, ''])

  @staticmethod
  def _MakeSection(title, body):
    header_line = TextResultsReport.H2_STR
    # '\n' at the end gives us two newlines.
    return '\n'.join([header_line, title, header_line, body, '\n'])

  @staticmethod
  def FromExperiment(experiment, email=False):
    results = BenchmarkResults.FromExperiment(experiment)
    return TextResultsReport(results, email, experiment)

  def GetStatusTable(self):
    """Generate the status table by the tabulator."""
    table = [['', '']]
    columns = [
        Column(LiteralResult(iteration=0), Format(), 'Status'), Column(
            LiteralResult(iteration=1), Format(), 'Failing Reason')
    ]

    for benchmark_run in self.experiment.benchmark_runs:
      status = [
          benchmark_run.name,
          [benchmark_run.timeline.GetLastEvent(), benchmark_run.failure_reason]
      ]
      table.append(status)
    cell_table = TableFormatter(table, columns).GetCellTable('status')
    return [cell_table]

  def GetReport(self):
    """Generate the report for email and console."""
    output_type = 'EMAIL' if self.email else 'CONSOLE'
    experiment = self.experiment

    sections = []
    if experiment is not None:
      title_contents = "Results report for '%s'" % (experiment.name,)
    else:
      title_contents = 'Results report'
    sections.append(self._MakeTitle(title_contents))

    if not self.benchmark_results.cwp_dso:
      summary_table = _PrintTable(self.GetSummaryTables(), output_type)
    else:
      summary_table = _PrintTable(self.GetSummaryTables(summary_type='cpu'),
                                  output_type)
    sections.append(self._MakeSection('Summary', summary_table))

    if experiment is not None:
      table = _PrintTable(self.GetStatusTable(), output_type)
      sections.append(self._MakeSection('Benchmark Run Status', table))

    perf_table = _PrintTable(self.GetSummaryTables(summary_type='perf'),
                             output_type)
    if perf_table and not self.benchmark_results.cwp_dso:
      sections.append(self._MakeSection('Perf Data', perf_table))

    if experiment is not None:
      experiment_file = experiment.experiment_file
      sections.append(self._MakeSection('Experiment File', experiment_file))

      cpu_info = experiment.machine_manager.GetAllCPUInfo(experiment.labels)
      sections.append(self._MakeSection('CPUInfo', cpu_info))

    return '\n'.join(sections)


def _GetHTMLCharts(label_names, test_results):
  charts = []
  for item, runs in test_results.iteritems():
    # Fun fact: label_names is actually *entirely* useless as a param, since we
    # never add headers. We still need to pass it anyway.
    table = TableGenerator(runs, label_names).GetTable()
    columns = [
        Column(AmeanResult(), Format()), Column(MinResult(), Format()), Column(
            MaxResult(), Format())
    ]
    tf = TableFormatter(table, columns)
    data_table = tf.GetCellTable('full', headers=False)

    for cur_row_data in data_table:
      test_key = cur_row_data[0].string_value
      title = '{0}: {1}'.format(item, test_key.replace('/', ''))
      chart = ColumnChart(title, 300, 200)
      chart.AddColumn('Label', 'string')
      chart.AddColumn('Average', 'number')
      chart.AddColumn('Min', 'number')
      chart.AddColumn('Max', 'number')
      chart.AddSeries('Min', 'line', 'black')
      chart.AddSeries('Max', 'line', 'black')
      cur_index = 1
      for label in label_names:
        chart.AddRow([
            label, cur_row_data[cur_index].value,
            cur_row_data[cur_index + 1].value, cur_row_data[cur_index + 2].value
        ])
        if isinstance(cur_row_data[cur_index].value, str):
          chart = None
          break
        cur_index += 3
      if chart:
        charts.append(chart)
  return charts


class HTMLResultsReport(ResultsReport):
  """Class to generate html result report."""

  def __init__(self, benchmark_results, experiment=None):
    super(HTMLResultsReport, self).__init__(benchmark_results)
    self.experiment = experiment

  @staticmethod
  def FromExperiment(experiment):
    return HTMLResultsReport(
        BenchmarkResults.FromExperiment(experiment), experiment=experiment)

  def GetReport(self):
    label_names = self.benchmark_results.label_names
    test_results = self.benchmark_results.run_keyvals
    charts = _GetHTMLCharts(label_names, test_results)
    chart_javascript = ''.join(chart.GetJavascript() for chart in charts)
    chart_divs = ''.join(chart.GetDiv() for chart in charts)

    if not self.benchmark_results.cwp_dso:
      summary_table = self.GetSummaryTables()
      perf_table = self.GetSummaryTables(summary_type='perf')
    else:
      summary_table = self.GetSummaryTables(summary_type='cpu')
      perf_table = None
    full_table = self.GetFullTables()

    experiment_file = ''
    if self.experiment is not None:
      experiment_file = self.experiment.experiment_file
    # Use kwargs for sanity, and so that testing is a bit easier.
    return templates.GenerateHTMLPage(
        perf_table=perf_table,
        chart_js=chart_javascript,
        summary_table=summary_table,
        print_table=_PrintTable,
        chart_divs=chart_divs,
        full_table=full_table,
        experiment_file=experiment_file)


def ParseStandardPerfReport(report_data):
  """Parses the output of `perf report`.

  It'll parse the following:
  {{garbage}}
  # Samples: 1234M of event 'foo'

  1.23% command shared_object location function::name

  1.22% command shared_object location function2::name

  # Samples: 999K of event 'bar'

  0.23% command shared_object location function3::name
  {{etc.}}

  Into:
    {'foo': {'function::name': 1.23, 'function2::name': 1.22},
     'bar': {'function3::name': 0.23, etc.}}
  """
  # This function fails silently on its if it's handed a string (as opposed to a
  # list of lines). So, auto-split if we do happen to get a string.
  if isinstance(report_data, basestring):
    report_data = report_data.splitlines()

  # Samples: N{K,M,G} of event 'event-name'
  samples_regex = re.compile(r"#\s+Samples: \d+\S? of event '([^']+)'")

  # We expect lines like:
  # N.NN%  command  samples  shared_object  [location] symbol
  #
  # Note that we're looking at stripped lines, so there is no space at the
  # start.
  perf_regex = re.compile(r'^(\d+(?:.\d*)?)%'  # N.NN%
                          r'\s*\d+'  # samples count (ignored)
                          r'\s*\S+'  # command (ignored)
                          r'\s*\S+'  # shared_object (ignored)
                          r'\s*\[.\]'  # location (ignored)
                          r'\s*(\S.+)'  # function
                         )

  stripped_lines = (l.strip() for l in report_data)
  nonempty_lines = (l for l in stripped_lines if l)
  # Ignore all lines before we see samples_regex
  interesting_lines = itertools.dropwhile(lambda x: not samples_regex.match(x),
                                          nonempty_lines)

  first_sample_line = next(interesting_lines, None)
  # Went through the entire file without finding a 'samples' header. Quit.
  if first_sample_line is None:
    return {}

  sample_name = samples_regex.match(first_sample_line).group(1)
  current_result = {}
  results = {sample_name: current_result}
  for line in interesting_lines:
    samples_match = samples_regex.match(line)
    if samples_match:
      sample_name = samples_match.group(1)
      current_result = {}
      results[sample_name] = current_result
      continue

    match = perf_regex.match(line)
    if not match:
      continue
    percentage_str, func_name = match.groups()
    try:
      percentage = float(percentage_str)
    except ValueError:
      # Couldn't parse it; try to be "resilient".
      continue
    current_result[func_name] = percentage
  return results


def _ReadExperimentPerfReport(results_directory, label_name, benchmark_name,
                              benchmark_iteration):
  """Reads a perf report for the given benchmark. Returns {} on failure.

  The result should be a map of maps; it should look like:
  {perf_event_name: {function_name: pct_time_spent}}, e.g.
  {'cpu_cycles': {'_malloc': 10.0, '_free': 0.3, ...}}
  """
  raw_dir_name = label_name + benchmark_name + str(benchmark_iteration + 1)
  dir_name = ''.join(c for c in raw_dir_name if c.isalnum())
  file_name = os.path.join(results_directory, dir_name, 'perf.data.report.0')
  try:
    with open(file_name) as in_file:
      return ParseStandardPerfReport(in_file)
  except IOError:
    # Yes, we swallow any IO-related errors.
    return {}


# Split out so that testing (specifically: mocking) is easier
def _ExperimentToKeyvals(experiment, for_json_report):
  """Converts an experiment to keyvals."""
  return OrganizeResults(
      experiment.benchmark_runs, experiment.labels, json_report=for_json_report)


class BenchmarkResults(object):
  """The minimum set of fields that any ResultsReport will take."""

  def __init__(self,
               label_names,
               benchmark_names_and_iterations,
               run_keyvals,
               read_perf_report=None,
               cwp_dso=None,
               weights=None):
    if read_perf_report is None:

      def _NoPerfReport(*_args, **_kwargs):
        return {}

      read_perf_report = _NoPerfReport

    self.label_names = label_names
    self.benchmark_names_and_iterations = benchmark_names_and_iterations
    self.iter_counts = dict(benchmark_names_and_iterations)
    self.run_keyvals = run_keyvals
    self.read_perf_report = read_perf_report
    self.cwp_dso = cwp_dso
    self.weights = dict(weights) if weights else None

  @staticmethod
  def FromExperiment(experiment, for_json_report=False):
    label_names = [label.name for label in experiment.labels]
    benchmark_names_and_iterations = [(benchmark.name, benchmark.iterations)
                                      for benchmark in experiment.benchmarks]
    run_keyvals = _ExperimentToKeyvals(experiment, for_json_report)
    read_perf_report = functools.partial(_ReadExperimentPerfReport,
                                         experiment.results_directory)
    cwp_dso = experiment.cwp_dso
    weights = [(benchmark.name, benchmark.weight)
               for benchmark in experiment.benchmarks]
    return BenchmarkResults(label_names, benchmark_names_and_iterations,
                            run_keyvals, read_perf_report, cwp_dso, weights)


def _GetElemByName(name, from_list):
  """Gets an element from the given list by its name field.

  Raises an error if it doesn't find exactly one match.
  """
  elems = [e for e in from_list if e.name == name]
  if len(elems) != 1:
    raise ValueError('Expected 1 item named %s, found %d' % (name, len(elems)))
  return elems[0]


def _Unlist(l):
  """If l is a list, extracts the first element of l. Otherwise, returns l."""
  return l[0] if isinstance(l, list) else l


class JSONResultsReport(ResultsReport):
  """Class that generates JSON reports for experiments."""

  def __init__(self,
               benchmark_results,
               date=None,
               time=None,
               experiment=None,
               json_args=None):
    """Construct a JSONResultsReport.

    json_args is the dict of arguments we pass to json.dumps in GetReport().
    """
    super(JSONResultsReport, self).__init__(benchmark_results)

    defaults = TelemetryDefaults()
    defaults.ReadDefaultsFile()
    summary_field_defaults = defaults.GetDefault()
    if summary_field_defaults is None:
      summary_field_defaults = {}
    self.summary_field_defaults = summary_field_defaults

    if json_args is None:
      json_args = {}
    self.json_args = json_args

    self.experiment = experiment
    if not date:
      timestamp = datetime.datetime.strftime(datetime.datetime.now(),
                                             '%Y-%m-%d %H:%M:%S')
      date, time = timestamp.split(' ')
    self.date = date
    self.time = time

  @staticmethod
  def FromExperiment(experiment, date=None, time=None, json_args=None):
    benchmark_results = BenchmarkResults.FromExperiment(
        experiment, for_json_report=True)
    return JSONResultsReport(benchmark_results, date, time, experiment,
                             json_args)

  def GetReportObjectIgnoringExperiment(self):
    """Gets the JSON report object specifically for the output data.

    Ignores any experiment-specific fields (e.g. board, machine checksum, ...).
    """
    benchmark_results = self.benchmark_results
    label_names = benchmark_results.label_names
    summary_field_defaults = self.summary_field_defaults
    final_results = []
    for test, test_results in benchmark_results.run_keyvals.iteritems():
      for label_name, label_results in zip(label_names, test_results):
        for iter_results in label_results:
          passed = iter_results.get('retval') == 0
          json_results = {
              'date': self.date,
              'time': self.time,
              'label': label_name,
              'test_name': test,
              'pass': passed,
          }
          final_results.append(json_results)

          if not passed:
            continue

          # Get overall results.
          summary_fields = summary_field_defaults.get(test)
          if summary_fields is not None:
            value = []
            json_results['overall_result'] = value
            for f in summary_fields:
              v = iter_results.get(f)
              if v is None:
                continue
              # New telemetry results format: sometimes we get a list of lists
              # now.
              v = _Unlist(_Unlist(v))
              value.append((f, float(v)))

          # Get detailed results.
          detail_results = {}
          json_results['detailed_results'] = detail_results
          for k, v in iter_results.iteritems():
            if k == 'retval' or k == 'PASS' or k == ['PASS'] or v == 'PASS':
              continue

            v = _Unlist(v)
            if 'machine' in k:
              json_results[k] = v
            elif v is not None:
              if isinstance(v, list):
                detail_results[k] = [float(d) for d in v]
              else:
                detail_results[k] = float(v)
    return final_results

  def GetReportObject(self):
    """Generate the JSON report, returning it as a python object."""
    report_list = self.GetReportObjectIgnoringExperiment()
    if self.experiment is not None:
      self._AddExperimentSpecificFields(report_list)
    return report_list

  def _AddExperimentSpecificFields(self, report_list):
    """Add experiment-specific data to the JSON report."""
    board = self.experiment.labels[0].board
    manager = self.experiment.machine_manager
    for report in report_list:
      label_name = report['label']
      label = _GetElemByName(label_name, self.experiment.labels)

      img_path = os.path.realpath(os.path.expanduser(label.chromeos_image))
      ver, img = ParseChromeosImage(img_path)

      report.update({
          'board': board,
          'chromeos_image': img,
          'chromeos_version': ver,
          'chrome_version': label.chrome_version,
          'compiler': label.compiler
      })

      if not report['pass']:
        continue
      if 'machine_checksum' not in report:
        report['machine_checksum'] = manager.machine_checksum[label_name]
      if 'machine_string' not in report:
        report['machine_string'] = manager.machine_checksum_string[label_name]

  def GetReport(self):
    """Dump the results of self.GetReportObject() to a string as JSON."""
    # This exists for consistency with the other GetReport methods.
    # Specifically, they all return strings, so it's a bit awkward if the JSON
    # results reporter returns an object.
    return json.dumps(self.GetReportObject(), **self.json_args)
