#!/usr/bin/python

'''
Copyright 2012 Google Inc.

Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
'''

'''
Rebaselines the given GM tests, on all bots and all configurations.
'''

# System-level imports
import argparse
import json
import os
import re
import subprocess
import sys
import urllib2

# Imports from within Skia
#
# We need to add the 'gm' directory, so that we can import gm_json.py within
# that directory.  That script allows us to parse the actual-results.json file
# written out by the GM tool.
# Make sure that the 'gm' dir is in the PYTHONPATH, but add it at the *end*
# so any dirs that are already in the PYTHONPATH will be preferred.
#
# This assumes that the 'gm' directory has been checked out as a sibling of
# the 'tools' directory containing this script, which will be the case if
# 'trunk' was checked out as a single unit.
GM_DIRECTORY = os.path.realpath(
    os.path.join(os.path.dirname(os.path.dirname(__file__)), 'gm'))
if GM_DIRECTORY not in sys.path:
  sys.path.append(GM_DIRECTORY)
import gm_json

# TODO(epoger): In the long run, we want to build this list automatically,
# but for now we hard-code it until we can properly address
# https://code.google.com/p/skia/issues/detail?id=1544
# ('live query of builder list makes rebaseline.py slow to start up')
TEST_BUILDERS = [
    'Test-Android-GalaxyNexus-SGX540-Arm7-Debug',
    'Test-Android-GalaxyNexus-SGX540-Arm7-Release',
    'Test-Android-IntelRhb-SGX544-x86-Debug',
    'Test-Android-IntelRhb-SGX544-x86-Release',
    'Test-Android-Nexus10-MaliT604-Arm7-Debug',
    'Test-Android-Nexus10-MaliT604-Arm7-Release',
    'Test-Android-Nexus4-Adreno320-Arm7-Debug',
    'Test-Android-Nexus4-Adreno320-Arm7-Release',
    'Test-Android-Nexus7-Tegra3-Arm7-Debug',
    'Test-Android-Nexus7-Tegra3-Arm7-Release',
    'Test-Android-NexusS-SGX540-Arm7-Debug',
    'Test-Android-NexusS-SGX540-Arm7-Release',
    'Test-Android-Xoom-Tegra2-Arm7-Debug',
    'Test-Android-Xoom-Tegra2-Arm7-Release',
    'Test-ChromeOS-Alex-GMA3150-x86-Debug',
    'Test-ChromeOS-Alex-GMA3150-x86-Release',
    'Test-ChromeOS-Daisy-MaliT604-Arm7-Debug',
    'Test-ChromeOS-Daisy-MaliT604-Arm7-Release',
    'Test-ChromeOS-Link-HD4000-x86_64-Debug',
    'Test-ChromeOS-Link-HD4000-x86_64-Release',
    'Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug',
    'Test-Mac10.6-MacMini4.1-GeForce320M-x86-Release',
    'Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Debug',
    'Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Release',
    'Test-Mac10.7-MacMini4.1-GeForce320M-x86-Debug',
    'Test-Mac10.7-MacMini4.1-GeForce320M-x86-Release',
    'Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug',
    'Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Release',
    'Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug',
    'Test-Mac10.8-MacMini4.1-GeForce320M-x86-Release',
    'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug',
    'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Release',
    'Test-Ubuntu12-ShuttleA-HD2000-x86_64-Release-Valgrind',
    'Test-Ubuntu12-ShuttleA-GTX660-x86-Debug',
    'Test-Ubuntu12-ShuttleA-GTX660-x86-Release',
    'Test-Ubuntu12-ShuttleA-GTX660-x86_64-Debug',
    'Test-Ubuntu12-ShuttleA-GTX660-x86_64-Release',
    'Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug',
    'Test-Win7-ShuttleA-HD2000-x86-Debug',
    'Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE',
    'Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite',
    'Test-Win7-ShuttleA-HD2000-x86-Release',
    'Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE',
    'Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite',
    'Test-Win7-ShuttleA-HD2000-x86_64-Debug',
    'Test-Win7-ShuttleA-HD2000-x86_64-Release',
    'Test-Win8-ShuttleA-GTX660-x86-Debug',
    'Test-Win8-ShuttleA-GTX660-x86-Release',
    'Test-Win8-ShuttleA-GTX660-x86_64-Debug',
    'Test-Win8-ShuttleA-GTX660-x86_64-Release',
    'Test-Win8-ShuttleA-HD7770-x86-Debug',
    'Test-Win8-ShuttleA-HD7770-x86-Release',
    'Test-Win8-ShuttleA-HD7770-x86_64-Debug',
    'Test-Win8-ShuttleA-HD7770-x86_64-Release',
]

# TODO: Get this from builder_name_schema in buildbot.
TRYBOT_SUFFIX = '-Trybot'


class _InternalException(Exception):
  pass

class ExceptionHandler(object):
  """ Object that handles exceptions, either raising them immediately or
  collecting them to display later on."""

  # params:
  def __init__(self, keep_going_on_failure=False):
    """
    params:
      keep_going_on_failure: if False, report failures and quit right away;
                             if True, collect failures until
                             ReportAllFailures() is called
    """
    self._keep_going_on_failure = keep_going_on_failure
    self._failures_encountered = []

  def RaiseExceptionOrContinue(self):
    """ We have encountered an exception; either collect the info and keep
    going, or exit the program right away."""
    # Get traceback information about the most recently raised exception.
    exc_info = sys.exc_info()

    if self._keep_going_on_failure:
      print >> sys.stderr, ('WARNING: swallowing exception %s' %
                            repr(exc_info[1]))
      self._failures_encountered.append(exc_info)
    else:
      print >> sys.stderr, (
          '\nHalting at first exception.\n' +
          'Please file a bug to epoger@google.com at ' +
          'https://code.google.com/p/skia/issues/entry, containing the ' +
          'command you ran and the following stack trace.\n\n' +
          'Afterwards, you can re-run with the --keep-going-on-failure ' +
          'option set.\n')
      raise exc_info[1], None, exc_info[2]

  def ReportAllFailures(self):
    if self._failures_encountered:
      print >> sys.stderr, ('Encountered %d failures (see above).' %
                            len(self._failures_encountered))
      sys.exit(1)


# Object that rebaselines a JSON expectations file (not individual image files).
class JsonRebaseliner(object):

  # params:
  #  expectations_root: root directory of all expectations JSON files
  #  expectations_input_filename: filename (under expectations_root) of JSON
  #                               expectations file to read; typically
  #                               "expected-results.json"
  #  expectations_output_filename: filename (under expectations_root) to
  #                                which updated expectations should be
  #                                written; typically the same as
  #                                expectations_input_filename, to overwrite
  #                                the old content
  #  actuals_base_url: base URL from which to read actual-result JSON files
  #  actuals_filename: filename (under actuals_base_url) from which to read a
  #                    summary of results; typically "actual-results.json"
  #  exception_handler: reference to rebaseline.ExceptionHandler object
  #  tests: list of tests to rebaseline, or None if we should rebaseline
  #         whatever files the JSON results summary file tells us to
  #  configs: which configs to run for each test, or None if we should
  #           rebaseline whatever configs the JSON results summary file tells
  #           us to
  #  add_new: if True, add expectations for tests which don't have any yet
  #  add_ignored: if True, add expectations for tests for which failures are
  #               currently ignored
  #  bugs: optional list of bug numbers which pertain to these expectations
  #  notes: free-form text notes to add to all updated expectations
  #  mark_unreviewed: if True, mark these expectations as NOT having been
  #                   reviewed by a human; otherwise, leave that field blank.
  #                   Currently, there is no way to make this script mark
  #                   expectations as reviewed-by-human=True.
  #                   TODO(epoger): Add that capability to a review tool.
  #  mark_ignore_failure: if True, mark failures of a given test as being
  #                       ignored.
  #  from_trybot: if True, read actual-result JSON files generated from a
  #               trybot run rather than a waterfall run.
  def __init__(self, expectations_root, expectations_input_filename,
               expectations_output_filename, actuals_base_url,
               actuals_filename, exception_handler,
               tests=None, configs=None, add_new=False, add_ignored=False,
               bugs=None, notes=None, mark_unreviewed=None,
               mark_ignore_failure=False, from_trybot=False):
    self._expectations_root = expectations_root
    self._expectations_input_filename = expectations_input_filename
    self._expectations_output_filename = expectations_output_filename
    self._tests = tests
    self._configs = configs
    self._actuals_base_url = actuals_base_url
    self._actuals_filename = actuals_filename
    self._exception_handler = exception_handler
    self._add_new = add_new
    self._add_ignored = add_ignored
    self._bugs = bugs
    self._notes = notes
    self._mark_unreviewed = mark_unreviewed
    self._mark_ignore_failure = mark_ignore_failure;
    if self._tests or self._configs:
      self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
    else:
      self._image_filename_re = None
    self._using_svn = os.path.isdir(os.path.join(expectations_root, '.svn'))
    self._from_trybot = from_trybot

  # Executes subprocess.call(cmd).
  # Raises an Exception if the command fails.
  def _Call(self, cmd):
    if subprocess.call(cmd) != 0:
      raise _InternalException('error running command: ' + ' '.join(cmd))

  # Returns the full contents of filepath, as a single string.
  # If filepath looks like a URL, try to read it that way instead of as
  # a path on local storage.
  #
  # Raises _InternalException if there is a problem.
  def _GetFileContents(self, filepath):
    if filepath.startswith('http:') or filepath.startswith('https:'):
      try:
        return urllib2.urlopen(filepath).read()
      except urllib2.HTTPError as e:
        raise _InternalException('unable to read URL %s: %s' % (
            filepath, e))
    else:
      return open(filepath, 'r').read()

  # Returns a dictionary of actual results from actual-results.json file.
  #
  # The dictionary returned has this format:
  # {
  #  u'imageblur_565.png': [u'bitmap-64bitMD5', 3359963596899141322],
  #  u'imageblur_8888.png': [u'bitmap-64bitMD5', 4217923806027861152],
  #  u'shadertext3_8888.png': [u'bitmap-64bitMD5', 3713708307125704716]
  # }
  #
  # If the JSON actual result summary file cannot be loaded, logs a warning
  # message and returns None.
  # If the JSON actual result summary file can be loaded, but we have
  # trouble parsing it, raises an Exception.
  #
  # params:
  #  json_url: URL pointing to a JSON actual result summary file
  #  sections: a list of section names to include in the results, e.g.
  #            [gm_json.JSONKEY_ACTUALRESULTS_FAILED,
  #             gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON] ;
  #            if None, then include ALL sections.
  def _GetActualResults(self, json_url, sections=None):
    try:
      json_contents = self._GetFileContents(json_url)
    except _InternalException:
      print >> sys.stderr, (
          'could not read json_url %s ; skipping this platform.' %
          json_url)
      return None
    json_dict = gm_json.LoadFromString(json_contents)
    results_to_return = {}
    actual_results = json_dict[gm_json.JSONKEY_ACTUALRESULTS]
    if not sections:
      sections = actual_results.keys()
    for section in sections:
      section_results = actual_results[section]
      if section_results:
        results_to_return.update(section_results)
    return results_to_return

  # Rebaseline all tests/types we specified in the constructor,
  # within this builder's subdirectory in expectations/gm .
  #
  # params:
  #  builder : e.g. 'Test-Win7-ShuttleA-HD2000-x86-Release'
  def RebaselineSubdir(self, builder):
    # Read in the actual result summary, and extract all the tests whose
    # results we need to update.
    results_builder = str(builder)
    if self._from_trybot:
      results_builder = results_builder + TRYBOT_SUFFIX
    actuals_url = '/'.join([self._actuals_base_url, results_builder,
                            self._actuals_filename])
    # Only update results for tests that are currently failing.
    # We don't want to rewrite results for tests that are already succeeding,
    # because we don't want to add annotation fields (such as
    # JSONKEY_EXPECTEDRESULTS_BUGS) except for tests whose expectations we
    # are actually modifying.
    sections = [gm_json.JSONKEY_ACTUALRESULTS_FAILED]
    if self._add_new:
      sections.append(gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON)
    if self._add_ignored:
      sections.append(gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED)
    results_to_update = self._GetActualResults(json_url=actuals_url,
                                               sections=sections)

    # Read in current expectations.
    expectations_input_filepath = os.path.join(
        self._expectations_root, builder, self._expectations_input_filename)
    expectations_dict = gm_json.LoadFromFile(expectations_input_filepath)
    expected_results = expectations_dict.get(gm_json.JSONKEY_EXPECTEDRESULTS)
    if not expected_results:
      expected_results = {}
      expectations_dict[gm_json.JSONKEY_EXPECTEDRESULTS] = expected_results

    # Update the expectations in memory, skipping any tests/configs that
    # the caller asked to exclude.
    skipped_images = []
    if results_to_update:
      for (image_name, image_results) in results_to_update.iteritems():
        if self._image_filename_re:
          (test, config) = self._image_filename_re.match(image_name).groups()
          if self._tests:
            if test not in self._tests:
              skipped_images.append(image_name)
              continue
          if self._configs:
            if config not in self._configs:
              skipped_images.append(image_name)
              continue
        if not expected_results.get(image_name):
          expected_results[image_name] = {}
        expected_results[image_name]\
                        [gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS]\
                        = [image_results]
        if self._mark_unreviewed:
          expected_results[image_name]\
                          [gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED]\
                          = False
        if self._mark_ignore_failure:
          expected_results[image_name]\
                          [gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE]\
                          = True
        if self._bugs:
          expected_results[image_name]\
                          [gm_json.JSONKEY_EXPECTEDRESULTS_BUGS]\
                          = self._bugs
        if self._notes:
          expected_results[image_name]\
                          [gm_json.JSONKEY_EXPECTEDRESULTS_NOTES]\
                          = self._notes

    # Write out updated expectations.
    expectations_output_filepath = os.path.join(
        self._expectations_root, builder, self._expectations_output_filename)
    gm_json.WriteToFile(expectations_dict, expectations_output_filepath)

    # Mark the JSON file as plaintext, so text-style diffs can be applied.
    # Fixes https://code.google.com/p/skia/issues/detail?id=1442
    if self._using_svn:
      self._Call(['svn', 'propset', '--quiet', 'svn:mime-type',
                  'text/x-json', expectations_output_filepath])

# main...

parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog='Here is the full set of builders we know about:' +
           '\n    '.join([''] + sorted(TEST_BUILDERS)))
parser.add_argument('--actuals-base-url',
                    help=('base URL from which to read files containing JSON '
                          'summaries of actual GM results; defaults to '
                          '%(default)s. To get a specific revision (useful for '
                          'trybots) replace "svn" with "svn-history/r123". '
                          'If SKIMAGE is True, defaults to ' +
                          gm_json.SKIMAGE_ACTUALS_BASE_URL),
                    default='http://skia-autogen.googlecode.com/svn/gm-actual')
parser.add_argument('--actuals-filename',
                    help=('filename (within builder-specific subdirectories '
                          'of ACTUALS_BASE_URL) to read a summary of results '
                          'from; defaults to %(default)s'),
                    default='actual-results.json')
parser.add_argument('--add-new', action='store_true',
                    help=('in addition to the standard behavior of '
                          'updating expectations for failing tests, add '
                          'expectations for tests which don\'t have '
                          'expectations yet.'))
parser.add_argument('--add-ignored', action='store_true',
                    help=('in addition to the standard behavior of '
                          'updating expectations for failing tests, add '
                          'expectations for tests for which failures are '
                          'currently ignored.'))
parser.add_argument('--bugs', metavar='BUG', type=int, nargs='+',
                    help=('Skia bug numbers (under '
                          'https://code.google.com/p/skia/issues/list ) which '
                          'pertain to this set of rebaselines.'))
parser.add_argument('--builders', metavar='BUILDER', nargs='+',
                    help=('which platforms to rebaseline; '
                          'if unspecified, rebaseline all known platforms '
                          '(see below for a list)'))
# TODO(epoger): Add test that exercises --configs argument.
parser.add_argument('--configs', metavar='CONFIG', nargs='+',
                    help=('which configurations to rebaseline, e.g. '
                          '"--configs 565 8888", as a filter over the full set '
                          'of results in ACTUALS_FILENAME; if unspecified, '
                          'rebaseline *all* configs that are available.'))
parser.add_argument('--deprecated', action='store_true',
                    help=('run the tool even though it has been deprecated; '
                          'see http://tinyurl.com/SkiaRebaselineServer for '
                          'the recommended/supported process'))
parser.add_argument('--expectations-filename',
                    help=('filename (under EXPECTATIONS_ROOT) to read '
                          'current expectations from, and to write new '
                          'expectations into (unless a separate '
                          'EXPECTATIONS_FILENAME_OUTPUT has been specified); '
                          'defaults to %(default)s'),
                    default='expected-results.json')
parser.add_argument('--expectations-filename-output',
                    help=('filename (under EXPECTATIONS_ROOT) to write '
                          'updated expectations into; by default, overwrites '
                          'the input file (EXPECTATIONS_FILENAME)'),
                    default='')
parser.add_argument('--expectations-root',
                    help=('root of expectations directory to update-- should '
                          'contain one or more builder subdirectories. '
                          'Defaults to %(default)s. If SKIMAGE is set, '
                          ' defaults to ' + gm_json.SKIMAGE_EXPECTATIONS_ROOT),
                    default=os.path.join('expectations', 'gm'))
parser.add_argument('--keep-going-on-failure', action='store_true',
                    help=('instead of halting at the first error encountered, '
                          'keep going and rebaseline as many tests as '
                          'possible, and then report the full set of errors '
                          'at the end'))
parser.add_argument('--notes',
                    help=('free-form text notes to add to all updated '
                          'expectations'))
# TODO(epoger): Add test that exercises --tests argument.
parser.add_argument('--tests', metavar='TEST', nargs='+',
                    help=('which tests to rebaseline, e.g. '
                          '"--tests aaclip bigmatrix", as a filter over the '
                          'full set of results in ACTUALS_FILENAME; if '
                          'unspecified, rebaseline *all* tests that are '
                          'available.'))
parser.add_argument('--unreviewed', action='store_true',
                    help=('mark all expectations modified by this run as '
                          '"%s": False' %
                          gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED))
parser.add_argument('--ignore-failure', action='store_true',
                    help=('mark all expectations modified by this run as '
                          '"%s": True' %
                          gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED))
parser.add_argument('--from-trybot', action='store_true',
                    help=('pull the actual-results.json file from the '
                          'corresponding trybot, rather than the main builder'))
parser.add_argument('--skimage', action='store_true',
                    help=('Rebaseline skimage results instead of gm. Defaults '
                          'to False. If True, TESTS and CONFIGS are ignored, '
                          'and ACTUALS_BASE_URL and EXPECTATIONS_ROOT are set '
                          'to alternate defaults, specific to skimage.'))
args = parser.parse_args()
if not args.deprecated:
  raise Exception(
      'This tool has been deprecated; see'
      ' http://tinyurl.com/SkiaRebaselineServer for the recommended/supported'
      ' process, or re-run with the --deprecated option to press on.')
exception_handler = ExceptionHandler(
    keep_going_on_failure=args.keep_going_on_failure)
if args.builders:
  builders = args.builders
  missing_json_is_fatal = True
else:
  builders = sorted(TEST_BUILDERS)
  missing_json_is_fatal = False
if args.skimage:
  # Use a different default if --skimage is specified.
  if args.actuals_base_url == parser.get_default('actuals_base_url'):
    args.actuals_base_url = gm_json.SKIMAGE_ACTUALS_BASE_URL
  if args.expectations_root == parser.get_default('expectations_root'):
    args.expectations_root = gm_json.SKIMAGE_EXPECTATIONS_ROOT
for builder in builders:
  if not builder in TEST_BUILDERS:
    raise Exception(('unrecognized builder "%s"; ' +
                     'should be one of %s') % (
                         builder, TEST_BUILDERS))

  expectations_json_file = os.path.join(args.expectations_root, builder,
                                        args.expectations_filename)
  if os.path.isfile(expectations_json_file):
    rebaseliner = JsonRebaseliner(
        expectations_root=args.expectations_root,
        expectations_input_filename=args.expectations_filename,
        expectations_output_filename=(args.expectations_filename_output or
                                      args.expectations_filename),
        tests=args.tests, configs=args.configs,
        actuals_base_url=args.actuals_base_url,
        actuals_filename=args.actuals_filename,
        exception_handler=exception_handler,
        add_new=args.add_new, add_ignored=args.add_ignored,
        bugs=args.bugs, notes=args.notes,
        mark_unreviewed=args.unreviewed,
        mark_ignore_failure=args.ignore_failure,
        from_trybot=args.from_trybot)
    try:
      rebaseliner.RebaselineSubdir(builder=builder)
    except:
      exception_handler.RaiseExceptionOrContinue()
  else:
    try:
      raise _InternalException('expectations_json_file %s not found' %
                               expectations_json_file)
    except:
      exception_handler.RaiseExceptionOrContinue()

exception_handler.ReportAllFailures()
