#!/usr/bin/python

# Copyright (c) 2014 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.


"""Generate new bench expectations from results of trybots on a code review."""


import collections
import compare_codereview
import os
import re
import shutil
import subprocess
import sys


BENCH_DATA_URL = 'gs://chromium-skia-gm/perfdata/%s/%s/*'
CHECKOUT_PATH = os.path.realpath(os.path.join(
    os.path.dirname(os.path.abspath(__file__)), os.pardir))
TMP_BENCH_DATA_DIR = os.path.join(CHECKOUT_PATH, '.bench_data')


def find_all_builds(codereview_url):
  """Finds and returns information about trybot runs for a code review.

  Args:
    codereview_url: URL of the codereview in question.

  Returns:
      List of NamedTuples: (builder_name, build_number, is_finished)
  """
  results = compare_codereview.CodeReviewHTMLParser().parse(codereview_url)
  TryBuild = collections.namedtuple(
      'TryBuild', ['builder_name', 'build_number', 'is_finished'])
  try_builds = []

  for builder, data in results.iteritems():
    if builder.startswith('Perf'):
      try_builds.append(TryBuild(builder, data.url.split('/')[-1],
                                 data.status != 'pending'))
  return try_builds


def get_bench_data(builder, build_num, dest_dir):
  """Download the bench data for the given builder at the given build_num.

  Args:
      builder: string; name of the builder.
      build_num: string; build number.
      dest_dir: string; destination directory for the bench data.
  """
  url = BENCH_DATA_URL % (builder, build_num)
  subprocess.check_call(['gsutil', 'cp', '-R', url, dest_dir],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)


def find_revision_from_downloaded_data(dest_dir):
  """Finds the revision at which the downloaded data was generated.

  Args:
      dest_dir: string; directory holding the downloaded data.

  Returns:
      The revision (git commit hash) at which the downloaded data was
      generated, or None if no revision can be found.
  """
  for data_file in os.listdir(dest_dir):
    match = re.match('bench_(?P<revision>[0-9a-fA-F]{2,40})_data.*', data_file)
    if match:
      return match.group('revision')
  return None


class TrybotNotFinishedError(Exception):
  pass


def gen_bench_expectations_from_codereview(codereview_url,
                                           error_on_unfinished=True):
  """Generate bench expectations from a code review.

  Scans the given code review for Perf trybot runs. Downloads the results of
  finished trybots and uses them to generate new expectations for their
  waterfall counterparts.

  Args:
      url: string; URL of the code review.
      error_on_unfinished: bool; throw an error if any trybot has not finished.
  """
  try_builds = find_all_builds(codereview_url)

  # Verify that all trybots have finished running.
  if error_on_unfinished:
    for try_build in try_builds:
      if not try_build.is_finished:
        raise TrybotNotFinishedError('%s: #%s is not finished.' % (
                                         try_build.builder_name,
                                         try_build.build_number))
  failed_data_pull = []
  failed_gen_expectations = []

  if os.path.isdir(TMP_BENCH_DATA_DIR):
    shutil.rmtree(TMP_BENCH_DATA_DIR)

  for try_build in try_builds:
    try_builder = try_build.builder_name
    builder = try_builder.replace('-Trybot', '')

    # Download the data.
    dest_dir = os.path.join(TMP_BENCH_DATA_DIR, builder)
    os.makedirs(dest_dir)
    try:
      get_bench_data(try_builder, try_build.build_number, dest_dir)
    except subprocess.CalledProcessError:
      failed_data_pull.append(try_builder)
      continue

    # Find the revision at which the data was generated.
    revision = find_revision_from_downloaded_data(dest_dir)
    if not revision:
      # If we can't find a revision, then something is wrong with the data we
      # downloaded. Skip this builder.
      failed_data_pull.append(try_builder)
      continue

    # Generate new expectations.
    output_file = os.path.join(CHECKOUT_PATH, 'expectations', 'bench',
                               'bench_expectations_%s.txt' % builder)
    try:
      subprocess.check_call(['python',
                             os.path.join(CHECKOUT_PATH, 'bench',
                                          'gen_bench_expectations.py'),
                             '-b', builder, '-o', output_file,
                             '-d', dest_dir, '-r', revision])
    except subprocess.CalledProcessError:
      failed_gen_expectations.append(builder)

  failure = ''
  if failed_data_pull:
    failure += 'Failed to load data for: %s\n\n' % ','.join(failed_data_pull)
  if failed_gen_expectations:
    failure += 'Failed to generate expectations for: %s\n\n' % ','.join(
        failed_gen_expectations)
  if failure:
    raise Exception(failure)


if __name__ == '__main__':
  gen_bench_expectations_from_codereview(sys.argv[1])

