#!/usr/bin/env python
# Copyright 2017 The PDFium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Compares the performance of two versions of the pdfium code."""

import argparse
import functools
import glob
import json
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import tempfile

from common import GetBooleanGnArg
from common import PrintErr
from common import RunCommandPropagateErr
from githelper import GitHelper
from safetynet_conclusions import ComparisonConclusions
from safetynet_conclusions import PrintConclusionsDictHumanReadable
from safetynet_conclusions import RATING_IMPROVEMENT
from safetynet_conclusions import RATING_REGRESSION
from safetynet_image import ImageComparison


def RunSingleTestCaseParallel(this, run_label, build_dir, test_case):
  result = this.RunSingleTestCase(run_label, build_dir, test_case)
  return (test_case, result)


class CompareRun(object):
  """A comparison between two branches of pdfium."""

  def __init__(self, args):
    self.git = GitHelper()
    self.args = args
    self._InitPaths()

  def _InitPaths(self):
    if self.args.this_repo:
      self.safe_script_dir = self.args.build_dir
    else:
      self.safe_script_dir = os.path.join('testing', 'tools')

    self.safe_measure_script_path = os.path.abspath(
        os.path.join(self.safe_script_dir,
                     'safetynet_measure.py'))

    input_file_re = re.compile('^.+[.]pdf$')
    self.test_cases = []
    for input_path in self.args.input_paths:
      if os.path.isfile(input_path):
        self.test_cases.append(input_path)
      elif os.path.isdir(input_path):
        for file_dir, _, filename_list in os.walk(input_path):
          for input_filename in filename_list:
            if input_file_re.match(input_filename):
              file_path = os.path.join(file_dir, input_filename)
              if os.path.isfile(file_path):
                self.test_cases.append(file_path)

    self.after_build_dir = self.args.build_dir
    if self.args.build_dir_before:
      self.before_build_dir = self.args.build_dir_before
    else:
      self.before_build_dir = self.after_build_dir

  def Run(self):
    """Runs comparison by checking out branches, building and measuring them.

    Returns:
      Exit code for the script.
    """
    if self.args.this_repo:
      self._FreezeMeasureScript()

    if self.args.branch_after:
      if self.args.this_repo:
        before, after = self._ProfileTwoOtherBranchesInThisRepo(
            self.args.branch_before,
            self.args.branch_after)
      else:
        before, after = self._ProfileTwoOtherBranches(
            self.args.branch_before,
            self.args.branch_after)
    elif self.args.branch_before:
      if self.args.this_repo:
        before, after = self._ProfileCurrentAndOtherBranchInThisRepo(
            self.args.branch_before)
      else:
        before, after = self._ProfileCurrentAndOtherBranch(
            self.args.branch_before)
    else:
      if self.args.this_repo:
        before, after = self._ProfileLocalChangesAndCurrentBranchInThisRepo()
      else:
        before, after = self._ProfileLocalChangesAndCurrentBranch()

    conclusions = self._DrawConclusions(before, after)
    conclusions_dict = conclusions.GetOutputDict()
    conclusions_dict.setdefault('metadata', {})['profiler'] = self.args.profiler

    self._PrintConclusions(conclusions_dict)

    self._CleanUp(conclusions)

    if self.args.png_dir:
      image_comparison = ImageComparison(
          self.after_build_dir,
          self.args.png_dir,
          ('before', 'after'),
          self.args.num_workers,
          self.args.png_threshold)
      image_comparison.Run(open_in_browser=not self.args.machine_readable)

    return 0

  def _FreezeMeasureScript(self):
    """Freezes a version of the measuring script.

    This is needed to make sure we are comparing the pdfium library changes and
    not script changes that may happen between the two branches.
    """
    self.__FreezeFile(os.path.join('testing', 'tools', 'safetynet_measure.py'))
    self.__FreezeFile(os.path.join('testing', 'tools', 'common.py'))

  def __FreezeFile(self, file):
    RunCommandPropagateErr(['cp', file, self.safe_script_dir],
                           exit_status_on_error=1)

  def _ProfileTwoOtherBranchesInThisRepo(self, before_branch, after_branch):
    """Profiles two branches that are not the current branch.

    This is done in the local repository and changes may not be restored if the
    script fails or is interrupted.

    after_branch does not need to descend from before_branch, they will be
    measured the same way

    Args:
      before_branch: One branch to profile.
      after_branch: Other branch to profile.

    Returns:
      A tuple (before, after), where each of before and after is a dict
      mapping a test case name to the profiling values for that test case
      in the given branch.
    """
    branch_to_restore = self.git.GetCurrentBranchName()

    self._StashLocalChanges()

    self._CheckoutBranch(after_branch)
    self._BuildCurrentBranch(self.after_build_dir)
    after = self._MeasureCurrentBranch('after', self.after_build_dir)

    self._CheckoutBranch(before_branch)
    self._BuildCurrentBranch(self.before_build_dir)
    before = self._MeasureCurrentBranch('before', self.before_build_dir)

    self._CheckoutBranch(branch_to_restore)
    self._RestoreLocalChanges()

    return before, after

  def _ProfileTwoOtherBranches(self, before_branch, after_branch):
    """Profiles two branches that are not the current branch.

    This is done in new, cloned repositories, therefore it is safer but slower
    and requires downloads.

    after_branch does not need to descend from before_branch, they will be
    measured the same way

    Args:
      before_branch: One branch to profile.
      after_branch: Other branch to profile.

    Returns:
      A tuple (before, after), where each of before and after is a dict
      mapping a test case name to the profiling values for that test case
      in the given branch.
    """
    after = self._ProfileSeparateRepo('after',
                                      self.after_build_dir,
                                      after_branch)
    before = self._ProfileSeparateRepo('before',
                                       self.before_build_dir,
                                       before_branch)
    return before, after

  def _ProfileCurrentAndOtherBranchInThisRepo(self, other_branch):
    """Profiles the current branch (with uncommitted changes) and another one.

    This is done in the local repository and changes may not be restored if the
    script fails or is interrupted.

    The current branch does not need to descend from other_branch.

    Args:
      other_branch: Other branch to profile that is not the current.

    Returns:
      A tuple (before, after), where each of before and after is a dict
      mapping a test case name to the profiling values for that test case
      in the given branch. The current branch is considered to be "after" and
      the other branch is considered to be "before".
    """
    branch_to_restore = self.git.GetCurrentBranchName()

    self._BuildCurrentBranch(self.after_build_dir)
    after = self._MeasureCurrentBranch('after', self.after_build_dir)

    self._StashLocalChanges()

    self._CheckoutBranch(other_branch)
    self._BuildCurrentBranch(self.before_build_dir)
    before = self._MeasureCurrentBranch('before', self.before_build_dir)

    self._CheckoutBranch(branch_to_restore)
    self._RestoreLocalChanges()

    return before, after

  def _ProfileCurrentAndOtherBranch(self, other_branch):
    """Profiles the current branch (with uncommitted changes) and another one.

    This is done in new, cloned repositories, therefore it is safer but slower
    and requires downloads.

    The current branch does not need to descend from other_branch.

    Args:
      other_branch: Other branch to profile that is not the current. None will
          compare to the same branch.

    Returns:
      A tuple (before, after), where each of before and after is a dict
      mapping a test case name to the profiling values for that test case
      in the given branch. The current branch is considered to be "after" and
      the other branch is considered to be "before".
    """
    self._BuildCurrentBranch(self.after_build_dir)
    after = self._MeasureCurrentBranch('after', self.after_build_dir)

    before = self._ProfileSeparateRepo('before',
                                       self.before_build_dir,
                                       other_branch)

    return before, after

  def _ProfileLocalChangesAndCurrentBranchInThisRepo(self):
    """Profiles the current branch with and without uncommitted changes.

    This is done in the local repository and changes may not be restored if the
    script fails or is interrupted.

    Returns:
      A tuple (before, after), where each of before and after is a dict
      mapping a test case name to the profiling values for that test case
      using the given version. The current branch without uncommitted changes is
      considered to be "before" and with uncommitted changes is considered to be
      "after".
    """
    self._BuildCurrentBranch(self.after_build_dir)
    after = self._MeasureCurrentBranch('after', self.after_build_dir)

    pushed = self._StashLocalChanges()
    if not pushed and not self.args.build_dir_before:
      PrintErr('Warning: No local changes to compare')

    before_build_dir = self.before_build_dir

    self._BuildCurrentBranch(before_build_dir)
    before = self._MeasureCurrentBranch('before', before_build_dir)

    self._RestoreLocalChanges()

    return before, after

  def _ProfileLocalChangesAndCurrentBranch(self):
    """Profiles the current branch with and without uncommitted changes.

    This is done in new, cloned repositories, therefore it is safer but slower
    and requires downloads.

    Returns:
      A tuple (before, after), where each of before and after is a dict
      mapping a test case name to the profiling values for that test case
      using the given version. The current branch without uncommitted changes is
      considered to be "before" and with uncommitted changes is considered to be
      "after".
    """
    return self._ProfileCurrentAndOtherBranch(other_branch=None)

  def _ProfileSeparateRepo(self, run_label, relative_build_dir, branch):
    """Profiles a branch in a a temporary git repository.

    Args:
      run_label: String to differentiate this version of the code in output
          files from other versions.
      relative_build_dir: Path to the build dir in the current working dir to
          clone build args from.
      branch: Branch to checkout in the new repository. None will
          profile the same branch checked out in the original repo.
    Returns:
      A dict mapping each test case name to the profiling values for that
      test case.
    """
    build_dir = self._CreateTempRepo('repo_%s' % run_label,
                                     relative_build_dir,
                                     branch)

    self._BuildCurrentBranch(build_dir)
    return self._MeasureCurrentBranch(run_label, build_dir)

  def _CreateTempRepo(self, dir_name, relative_build_dir, branch):
    """Clones a temporary git repository out of the current working dir.

    Args:
      dir_name: Name for the temporary repository directory
      relative_build_dir: Path to the build dir in the current working dir to
          clone build args from.
      branch: Branch to checkout in the new repository. None will keep checked
          out the same branch as the local repo.
    Returns:
      Path to the build directory of the new repository.
    """
    cwd = os.getcwd()

    repo_dir = tempfile.mkdtemp(suffix='-%s' % dir_name)
    src_dir = os.path.join(repo_dir, 'pdfium')

    self.git.CloneLocal(os.getcwd(), src_dir)

    if branch is not None:
      os.chdir(src_dir)
      self.git.Checkout(branch)

    os.chdir(repo_dir)
    PrintErr('Syncing...')

    cmd = ['gclient', 'config', '--unmanaged',
           'https://pdfium.googlesource.com/pdfium.git']
    if self.args.cache_dir:
      cmd.append('--cache-dir=%s' % self.args.cache_dir)
    RunCommandPropagateErr(cmd, exit_status_on_error=1)

    RunCommandPropagateErr(['gclient', 'sync'], exit_status_on_error=1)

    PrintErr('Done.')

    build_dir = os.path.join(src_dir, relative_build_dir)
    os.makedirs(build_dir)
    os.chdir(src_dir)

    source_gn_args = os.path.join(cwd, relative_build_dir, 'args.gn')
    dest_gn_args = os.path.join(build_dir, 'args.gn')
    shutil.copy(source_gn_args, dest_gn_args)

    RunCommandPropagateErr(['gn', 'gen', relative_build_dir],
                           exit_status_on_error=1)

    os.chdir(cwd)

    return build_dir


  def _CheckoutBranch(self, branch):
    PrintErr("Checking out branch '%s'" % branch)
    self.git.Checkout(branch)

  def _StashLocalChanges(self):
    PrintErr('Stashing local changes')
    return self.git.StashPush()

  def _RestoreLocalChanges(self):
    PrintErr('Restoring local changes')
    self.git.StashPopAll()

  def _BuildCurrentBranch(self, build_dir):
    """Synchronizes and builds the current version of pdfium.

    Args:
      build_dir: String with path to build directory
    """
    PrintErr('Syncing...')
    RunCommandPropagateErr(['gclient', 'sync'], exit_status_on_error=1)
    PrintErr('Done.')

    PrintErr('Building...')
    cmd = ['ninja', '-C', build_dir, 'pdfium_test']
    if GetBooleanGnArg('use_goma', build_dir):
      cmd.extend(['-j', '250'])
    RunCommandPropagateErr(cmd, stdout_has_errors=True, exit_status_on_error=1)
    PrintErr('Done.')

  def _MeasureCurrentBranch(self, run_label, build_dir):
    PrintErr('Measuring...')
    if self.args.num_workers > 1 and len(self.test_cases) > 1:
      results = self._RunAsync(run_label, build_dir)
    else:
      results = self._RunSync(run_label, build_dir)
    PrintErr('Done.')

    return results

  def _RunSync(self, run_label, build_dir):
    """Profiles the test cases synchronously.

    Args:
      run_label: String to differentiate this version of the code in output
          files from other versions.
      build_dir: String with path to build directory

    Returns:
      A dict mapping each test case name to the profiling values for that
      test case.
    """
    results = {}

    for test_case in self.test_cases:
      result = self.RunSingleTestCase(run_label, build_dir, test_case)
      if result is not None:
        results[test_case] = result

    return results

  def _RunAsync(self, run_label, build_dir):
    """Profiles the test cases asynchronously.

    Uses as many workers as configured by --num-workers.

    Args:
      run_label: String to differentiate this version of the code in output
          files from other versions.
      build_dir: String with path to build directory

    Returns:
      A dict mapping each test case name to the profiling values for that
      test case.
    """
    results = {}
    pool = multiprocessing.Pool(self.args.num_workers)
    worker_func = functools.partial(
        RunSingleTestCaseParallel, self, run_label, build_dir)

    try:
      # The timeout is a workaround for http://bugs.python.org/issue8296
      # which prevents KeyboardInterrupt from working.
      one_year_in_seconds = 3600 * 24 * 365
      worker_results = (pool.map_async(worker_func, self.test_cases)
                        .get(one_year_in_seconds))
      for worker_result in worker_results:
        test_case, result = worker_result
        if result is not None:
          results[test_case] = result
    except KeyboardInterrupt:
      pool.terminate()
      sys.exit(1)
    else:
      pool.close()

    pool.join()

    return results

  def RunSingleTestCase(self, run_label, build_dir, test_case):
    """Profiles a single test case.

    Args:
      run_label: String to differentiate this version of the code in output
          files from other versions.
      build_dir: String with path to build directory
      test_case: Path to the test case.

    Returns:
      The measured profiling value for that test case.
    """
    command = [self.safe_measure_script_path, test_case,
               '--build-dir=%s' % build_dir]

    if self.args.interesting_section:
      command.append('--interesting-section')

    if self.args.profiler:
      command.append('--profiler=%s' % self.args.profiler)

    profile_file_path = self._GetProfileFilePath(run_label, test_case)
    if profile_file_path:
      command.append('--output-path=%s' % profile_file_path)

    if self.args.png_dir:
      command.append('--png')

    if self.args.pages:
      command.extend(['--pages', self.args.pages])

    output = RunCommandPropagateErr(command)

    if output is None:
      return None

    if self.args.png_dir:
      self._MoveImages(test_case, run_label)

    # Get the time number as output, making sure it's just a number
    output = output.strip()
    if re.match('^[0-9]+$', output):
      return int(output)

    return None

  def _MoveImages(self, test_case, run_label):
    png_dir = os.path.join(self.args.png_dir, run_label)
    if not os.path.exists(png_dir):
      os.makedirs(png_dir)

    test_case_dir, test_case_filename = os.path.split(test_case)
    test_case_png_matcher = '%s.*.png' % test_case_filename
    for output_png in glob.glob(os.path.join(test_case_dir,
                                             test_case_png_matcher)):
      shutil.move(output_png, png_dir)

  def _GetProfileFilePath(self, run_label, test_case):
    if self.args.output_dir:
      output_filename = ('callgrind.out.%s.%s'
                         % (test_case.replace('/', '_'),
                            run_label))
      return os.path.join(self.args.output_dir, output_filename)
    else:
      return None

  def _DrawConclusions(self, times_before_branch, times_after_branch):
    """Draws conclusions comparing results of test runs in two branches.

    Args:
      times_before_branch: A dict mapping each test case name to the
          profiling values for that test case in the branch to be considered
          as the baseline.
      times_after_branch: A dict mapping each test case name to the
          profiling values for that test case in the branch to be considered
          as the new version.

    Returns:
      ComparisonConclusions with all test cases processed.
    """
    conclusions = ComparisonConclusions(self.args.threshold_significant)

    for test_case in sorted(self.test_cases):
      before = times_before_branch.get(test_case)
      after = times_after_branch.get(test_case)
      conclusions.ProcessCase(test_case, before, after)

    return conclusions

  def _PrintConclusions(self, conclusions_dict):
    """Prints the conclusions as the script output.

    Depending on the script args, this can output a human or a machine-readable
    version of the conclusions.

    Args:
      conclusions_dict: Dict to print returned from
          ComparisonConclusions.GetOutputDict().
    """
    if self.args.machine_readable:
      print json.dumps(conclusions_dict)
    else:
      PrintConclusionsDictHumanReadable(
          conclusions_dict, colored=True, key=self.args.case_order)

  def _CleanUp(self, conclusions):
    """Removes profile output files for uninteresting cases.

    Cases without significant regressions or improvements and considered
    uninteresting.

    Args:
      conclusions: A ComparisonConclusions.
    """
    if not self.args.output_dir:
      return

    if self.args.profiler != 'callgrind':
      return

    for case_result in conclusions.GetCaseResults().values():
      if case_result.rating not in [RATING_REGRESSION, RATING_IMPROVEMENT]:
        self._CleanUpOutputFile('before', case_result.case_name)
        self._CleanUpOutputFile('after', case_result.case_name)

  def _CleanUpOutputFile(self, run_label, case_name):
    """Removes one profile output file.

    If the output file does not exist, fails silently.

    Args:
      run_label: String to differentiate a version of the code in output
          files from other versions.
      case_name: String identifying test case for which to remove the output
          file.
    """
    try:
      os.remove(self._GetProfileFilePath(run_label, case_name))
    except OSError:
      pass


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('input_paths', nargs='+',
                      help='pdf files or directories to search for pdf files '
                           'to run as test cases')
  parser.add_argument('--branch-before',
                      help='git branch to use as "before" for comparison. '
                           'Omitting this will use the current branch '
                           'without uncommitted changes as the baseline.')
  parser.add_argument('--branch-after',
                      help='git branch to use as "after" for comparison. '
                           'Omitting this will use the current branch '
                           'with uncommitted changes.')
  parser.add_argument('--build-dir', default=os.path.join('out', 'Release'),
                      help='relative path from the base source directory '
                           'to the build directory')
  parser.add_argument('--build-dir-before',
                      help='relative path from the base source directory '
                           'to the build directory for the "before" branch, if '
                           'different from the build directory for the '
                           '"after" branch')
  parser.add_argument('--cache-dir', default=None,
                      help='directory with a new or preexisting cache for '
                           'downloads. Default is to not use a cache.')
  parser.add_argument('--this-repo', action='store_true',
                      help='use the repository where the script is instead of '
                           'checking out a temporary one. This is faster and '
                           'does not require downloads, but although it '
                           'restores the state of the local repo, if the '
                           'script is killed or crashes the changes can remain '
                           'stashed and you may be on another branch.')
  parser.add_argument('--profiler', default='callgrind',
                      help='which profiler to use. Supports callgrind and '
                           'perfstat for now. Default is callgrind.')
  parser.add_argument('--interesting-section', action='store_true',
                      help='whether to measure just the interesting section or '
                           'the whole test harness. Limiting to only the '
                           'interesting section does not work on Release since '
                           'the delimiters are optimized out')
  parser.add_argument('--pages',
                      help='selects some pages to be rendered. Page numbers '
                           'are 0-based. "--pages A" will render only page A. '
                           '"--pages A-B" will render pages A to B '
                           '(inclusive).')
  parser.add_argument('--num-workers', default=multiprocessing.cpu_count(),
                      type=int, help='run NUM_WORKERS jobs in parallel')
  parser.add_argument('--output-dir',
                      help='directory to write the profile data output files')
  parser.add_argument('--png-dir', default=None,
                      help='outputs pngs to the specified directory that can '
                           'be compared with a static html generated. Will '
                           'affect performance measurements.')
  parser.add_argument('--png-threshold', default=0.0, type=float,
                      help='Requires --png-dir. Threshold above which a png '
                           'is considered to have changed.')
  parser.add_argument('--threshold-significant', default=0.02, type=float,
                      help='variations in performance above this factor are '
                           'considered significant')
  parser.add_argument('--machine-readable', action='store_true',
                      help='whether to get output for machines. If enabled the '
                           'output will be a json with the format specified in '
                           'ComparisonConclusions.GetOutputDict(). Default is '
                           'human-readable.')
  parser.add_argument('--case-order', default=None,
                      help='what key to use when sorting test cases in the '
                           'output. Accepted values are "after", "before", '
                           '"ratio" and "rating". Default is sorting by test '
                           'case path.')

  args = parser.parse_args()

  # Always start at the pdfium src dir, which is assumed to be two level above
  # this script.
  pdfium_src_dir = os.path.join(
      os.path.dirname(__file__),
      os.path.pardir,
      os.path.pardir)
  os.chdir(pdfium_src_dir)

  git = GitHelper()

  if args.branch_after and not args.branch_before:
    PrintErr('--branch-after requires --branch-before to be specified.')
    return 1

  if args.branch_after and not git.BranchExists(args.branch_after):
    PrintErr('Branch "%s" does not exist' % args.branch_after)
    return 1

  if args.branch_before and not git.BranchExists(args.branch_before):
    PrintErr('Branch "%s" does not exist' % args.branch_before)
    return 1

  if args.output_dir:
    args.output_dir = os.path.expanduser(args.output_dir)
    if not os.path.isdir(args.output_dir):
      PrintErr('"%s" is not a directory' % args.output_dir)
      return 1

  if args.png_dir:
    args.png_dir = os.path.expanduser(args.png_dir)
    if not os.path.isdir(args.png_dir):
      PrintErr('"%s" is not a directory' % args.png_dir)
      return 1

  if args.threshold_significant <= 0.0:
    PrintErr('--threshold-significant should receive a positive float')
    return 1

  if args.png_threshold:
    if not args.png_dir:
      PrintErr('--png-threshold requires --png-dir to be specified.')
      return 1

    if args.png_threshold <= 0.0:
      PrintErr('--png-threshold should receive a positive float')
      return 1

  if args.pages:
    if not re.match(r'^\d+(-\d+)?$', args.pages):
      PrintErr('Supported formats for --pages are "--pages 7" and '
               '"--pages 3-6"')
      return 1

  run = CompareRun(args)
  return run.Run()


if __name__ == '__main__':
  sys.exit(main())
