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


import json
import logging
import os
import time
import traceback

import buildbot_report
import constants


class BaseTestResult(object):
  """A single result from a unit test."""

  def __init__(self, name, log):
    self.name = name
    self.log = log.replace('\r', '')


class SingleTestResult(BaseTestResult):
  """Result information for a single test.

  Args:
    full_name: Full name of the test.
    start_date: Date in milliseconds when the test began running.
    dur: Duration of the test run in milliseconds.
    log: An optional string listing any errors.
  """

  def __init__(self, full_name, start_date, dur, log=''):
    BaseTestResult.__init__(self, full_name, log)
    name_pieces = full_name.rsplit('#')
    if len(name_pieces) > 1:
      self.test_name = name_pieces[1]
      self.class_name = name_pieces[0]
    else:
      self.class_name = full_name
      self.test_name = full_name
    self.start_date = start_date
    self.dur = dur


class TestResults(object):
  """Results of a test run."""

  def __init__(self):
    self.ok = []
    self.failed = []
    self.crashed = []
    self.unknown = []
    self.timed_out = False
    self.overall_fail = False
    self.device_exception = None

  @staticmethod
  def FromRun(ok=None, failed=None, crashed=None, timed_out=False,
              overall_fail=False, device_exception=None):
    ret = TestResults()
    ret.ok = ok or []
    ret.failed = failed or []
    ret.crashed = crashed or []
    ret.timed_out = timed_out
    ret.overall_fail = overall_fail
    ret.device_exception = device_exception
    return ret

  @staticmethod
  def FromTestResults(results):
    """Combines a list of results in a single TestResults object."""
    ret = TestResults()
    for t in results:
      ret.ok += t.ok
      ret.failed += t.failed
      ret.crashed += t.crashed
      ret.unknown += t.unknown
      if t.timed_out:
        ret.timed_out = True
      if t.overall_fail:
        ret.overall_fail = True
    return ret

  @staticmethod
  def FromPythonException(test_name, start_date_ms, exc_info):
    """Constructs a TestResults with exception information for the given test.

    Args:
      test_name: name of the test which raised an exception.
      start_date_ms: the starting time for the test.
      exc_info: exception info, ostensibly from sys.exc_info().

    Returns:
      A TestResults object with a SingleTestResult in the failed list.
    """
    exc_type, exc_value, exc_traceback = exc_info
    trace_info = ''.join(traceback.format_exception(exc_type, exc_value,
                                                    exc_traceback))
    log_msg = 'Exception:\n' + trace_info
    duration_ms = (int(time.time()) * 1000) - start_date_ms

    exc_result = SingleTestResult(
                     full_name='PythonWrapper#' + test_name,
                     start_date=start_date_ms,
                     dur=duration_ms,
                     log=(str(exc_type) + ' ' + log_msg))

    results = TestResults()
    results.failed.append(exc_result)
    return results

  @staticmethod
  def DeviceExceptions(results):
    return set(filter(lambda t: t.device_exception, results))

  def _Log(self, sorted_list):
    for t in sorted_list:
      logging.critical(t.name)
      if t.log:
        logging.critical(t.log)

  def GetAllBroken(self):
    """Returns the all broken tests including failed, crashed, unknown."""
    return self.failed + self.crashed + self.unknown

  def LogFull(self, test_group, test_suite, build_type, tests_to_run):
    """Output broken test logs, summarize in a log file and the test output."""
    # Output all broken tests or 'passed' if none broken.
    logging.critical('*' * 80)
    logging.critical('Final result')
    if self.failed:
      logging.critical('Failed:')
      self._Log(sorted(self.failed))
    if self.crashed:
      logging.critical('Crashed:')
      self._Log(sorted(self.crashed))
    if self.unknown:
      logging.critical('Unknown:')
      self._Log(sorted(self.unknown))
    if not self.GetAllBroken():
      logging.critical('Passed')
    logging.critical('*' * 80)

    # Summarize in a log file, if tests are running on bots.
    if test_group and test_suite and os.environ.get('BUILDBOT_BUILDERNAME'):
      log_file_path = os.path.join(constants.CHROME_DIR, 'out',
                                   build_type, 'test_logs')
      if not os.path.exists(log_file_path):
        os.mkdir(log_file_path)
      full_file_name = os.path.join(log_file_path, test_group)
      if not os.path.exists(full_file_name):
        with open(full_file_name, 'w') as log_file:
          print >> log_file, '\n%s results for %s build %s:' % (
              test_group, os.environ.get('BUILDBOT_BUILDERNAME'),
              os.environ.get('BUILDBOT_BUILDNUMBER'))
      log_contents = ['  %s result : %d tests ran' % (test_suite,
                                                      len(self.ok) +
                                                      len(self.failed) +
                                                      len(self.crashed) +
                                                      len(self.unknown))]
      content_pairs = [('passed', len(self.ok)), ('failed', len(self.failed)),
                       ('crashed', len(self.crashed))]
      for (result, count) in content_pairs:
        if count:
          log_contents.append(', %d tests %s' % (count, result))
      with open(full_file_name, 'a') as log_file:
        print >> log_file, ''.join(log_contents)
      content = {'test_group': test_group,
                 'ok': [t.name for t in self.ok],
                 'failed': [t.name for t in self.failed],
                 'crashed': [t.name for t in self.failed],
                 'unknown': [t.name for t in self.unknown],}
      with open(os.path.join(log_file_path, 'results.json'), 'a') as json_file:
        print >> json_file, json.dumps(content)

    # Summarize in the test output.
    summary = ['Summary:\n']
    if tests_to_run:
      summary += ['TESTS_TO_RUN=%d\n' % (len(tests_to_run))]
    num_tests_ran = (len(self.ok) + len(self.failed) +
                     len(self.crashed) + len(self.unknown))
    tests_passed = [t.name for t in self.ok]
    tests_failed = [t.name for t in self.failed]
    tests_crashed = [t.name for t in self.crashed]
    tests_unknown = [t.name for t in self.unknown]
    summary += ['RAN=%d\n' % (num_tests_ran),
                'PASSED=%d\n' % len(tests_passed),
                'FAILED=%d %s\n' % (len(tests_failed), tests_failed),
                'CRASHED=%d %s\n' % (len(tests_crashed), tests_crashed),
                'UNKNOWN=%d %s\n' % (len(tests_unknown), tests_unknown)]
    if tests_to_run and num_tests_ran != len(tests_to_run):
      # Add the list of tests we failed to run.
      tests_failed_to_run = list(set(tests_to_run) - set(tests_passed) -
                            set(tests_failed) - set(tests_crashed) -
                            set(tests_unknown))
      summary += ['FAILED_TO_RUN=%d %s\n' % (len(tests_failed_to_run),
                                             tests_failed_to_run)]
    summary_string = ''.join(summary)
    logging.critical(summary_string)
    return summary_string

  def PrintAnnotation(self):
    """Print buildbot annotations for test results."""
    if self.failed or self.crashed or self.overall_fail or self.timed_out:
      buildbot_report.PrintError()
    else:
      print 'Step success!'  # No annotation needed
