#!/usr/bin/env python
# Copyright 2017 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.

"""Tool for finding the cause of binary size bloat.

See //tools/binary_size/README.md for example usage.

Note: this tool will perform gclient sync/git checkout on your local repo if
you don't use the --cloud option.
"""

import atexit
import argparse
import collections
from contextlib import contextmanager
import distutils.spawn
import json
import logging
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import tempfile
import zipfile

_COMMIT_COUNT_WARN_THRESHOLD = 15
_ALLOWED_CONSECUTIVE_FAILURES = 2
_SRC_ROOT = os.path.abspath(
    os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
_DEFAULT_ARCHIVE_DIR = os.path.join(_SRC_ROOT, 'out', 'binary-size-results')
_DEFAULT_OUT_DIR = os.path.join(_SRC_ROOT, 'out', 'binary-size-build')
_BINARY_SIZE_DIR = os.path.join(_SRC_ROOT, 'tools', 'binary_size')
_RESOURCE_SIZES_PATH = os.path.join(
    _SRC_ROOT, 'build', 'android', 'resource_sizes.py')
_LLVM_TOOLS_DIR = os.path.join(
    _SRC_ROOT, 'third_party', 'llvm-build', 'Release+Asserts', 'bin')
_DOWNLOAD_OBJDUMP_PATH = os.path.join(
    _SRC_ROOT, 'tools', 'clang', 'scripts', 'download_objdump.py')


_DiffResult = collections.namedtuple('DiffResult', ['name', 'value', 'units'])


class BaseDiff(object):
  """Base class capturing binary size diffs."""
  def __init__(self, name):
    self.name = name
    self.banner = '\n' + '*' * 30 + name + '*' * 30

  def AppendResults(self, logfiles):
    """Print and write diff results to an open |logfile|."""
    full, short = logfiles
    _WriteToFile(full, self.banner)
    _WriteToFile(short, self.banner)

    for s in self.Summary():
      _WriteToFile(short, s)
    _WriteToFile(short, '')

    for s in self.DetailedResults():
      full.write(s + '\n')

  @property
  def summary_stat(self):
    """Returns a tuple of (name, value, units) for the most important metric."""
    raise NotImplementedError()

  def Summary(self):
    """A short description that summarizes the source of binary size bloat."""
    raise NotImplementedError()

  def DetailedResults(self):
    """An iterable description of the cause of binary size bloat."""
    raise NotImplementedError()

  def ProduceDiff(self, before_dir, after_dir):
    """Prepare a binary size diff with ready to print results."""
    raise NotImplementedError()

  def RunDiff(self, logfiles, before_dir, after_dir):
    logging.info('Creating: %s', self.name)
    self.ProduceDiff(before_dir, after_dir)
    self.AppendResults(logfiles)


class NativeDiff(BaseDiff):
  # E.g.: Section Sizes (Total=1.2 kb (1222 bytes)):
  _RE_SUMMARY_STAT = re.compile(
      r'Section Sizes \(Total=(?P<value>-?[0-9\.]+) ?(?P<units>\w+)')
  _SUMMARY_STAT_NAME = 'Native Library Delta'

  def __init__(self, size_name, supersize_path):
    self._size_name = size_name
    self._supersize_path = supersize_path
    self._diff = []
    super(NativeDiff, self).__init__('Native Diff')

  @property
  def summary_stat(self):
    m = NativeDiff._RE_SUMMARY_STAT.search(self._diff)
    if m:
      return _DiffResult(
          NativeDiff._SUMMARY_STAT_NAME, m.group('value'), m.group('units'))
    raise Exception('Could not extract total from:\n' + self._diff)

  def DetailedResults(self):
    return self._diff.splitlines()

  def Summary(self):
    return self.DetailedResults()[:100]

  def ProduceDiff(self, before_dir, after_dir):
    before_size = os.path.join(before_dir, self._size_name)
    after_size = os.path.join(after_dir, self._size_name)
    cmd = [self._supersize_path, 'diff', before_size, after_size]
    self._diff = _RunCmd(cmd)[0].replace('{', '{{').replace('}', '}}')


class ResourceSizesDiff(BaseDiff):
  # Ordered by output appearance.
  _SUMMARY_SECTIONS = (
      'Specifics', 'InstallSize', 'InstallBreakdown', 'Dex',
      'StaticInitializersCount')
  # Sections where it makes sense to sum subsections into a section total.
  _AGGREGATE_SECTIONS = (
      'InstallBreakdown', 'Breakdown', 'MainLibInfo', 'Uncompressed')

  def __init__(self, apk_name, filename='results-chart.json'):
    self._apk_name = apk_name
    self._diff = None  # Set by |ProduceDiff()|
    self._filename = filename
    super(ResourceSizesDiff, self).__init__('Resource Sizes Diff')

  @property
  def summary_stat(self):
    for section_name, results in self._diff.iteritems():
      for subsection_name, value, units in results:
        if 'normalized' in subsection_name:
          full_name = '{} {}'.format(section_name, subsection_name)
          return _DiffResult(full_name, value, units)
    raise Exception('Could not find "normalized" in: ' + repr(self._diff))

  def DetailedResults(self):
    return self._ResultLines()

  def Summary(self):
    header_lines = [
        'For an explanation of these metrics, see:',
        ('https://chromium.googlesource.com/chromium/src/+/master/docs/speed/'
         'binary_size/metrics.md#Metrics-for-Android'),
        '']
    return header_lines + self._ResultLines(
        include_sections=ResourceSizesDiff._SUMMARY_SECTIONS)

  def ProduceDiff(self, before_dir, after_dir):
    before = self._LoadResults(before_dir)
    after = self._LoadResults(after_dir)
    self._diff = collections.defaultdict(list)
    for section, section_dict in after.iteritems():
      for subsection, v in section_dict.iteritems():
        # Ignore entries when resource_sizes.py chartjson format has changed.
        if (section not in before or
            subsection not in before[section] or
            v['units'] != before[section][subsection]['units']):
          logging.warning(
              'Found differing dict structures for resource_sizes.py, '
              'skipping %s %s', section, subsection)
        else:
          self._diff[section].append(_DiffResult(
              subsection,
              v['value'] - before[section][subsection]['value'],
              v['units']))

  def _ResultLines(self, include_sections=None):
    """Generates diff lines for the specified sections (defaults to all)."""
    section_lines = collections.defaultdict(list)
    for section_name, section_results in self._diff.iteritems():
      section_no_target = re.sub(r'^.*_', '', section_name)
      if not include_sections or section_no_target in include_sections:
        subsection_lines = []
        section_sum = 0
        units = ''
        for name, value, units in section_results:
          # Omit subsections with no changes for summaries.
          if value == 0 and include_sections:
            continue
          section_sum += value
          subsection_lines.append('{:>+14,} {} {}'.format(value, units, name))
        section_header = section_no_target
        if section_no_target in ResourceSizesDiff._AGGREGATE_SECTIONS:
          section_header += ' ({:+,} {})'.format(section_sum, units)
        section_header += ':'
        # Omit sections with empty subsections.
        if subsection_lines:
          section_lines[section_no_target].append(section_header)
          section_lines[section_no_target].extend(subsection_lines)
    if not section_lines:
      return ['Empty ' + self.name]
    ret = []
    for k in include_sections or sorted(section_lines):
      ret.extend(section_lines[k])
    return ret

  def _LoadResults(self, archive_dir):
    chartjson_file = os.path.join(archive_dir, self._filename)
    with open(chartjson_file) as f:
      chartjson = json.load(f)
    return chartjson['charts']


class _BuildHelper(object):
  """Helper class for generating and building targets."""
  def __init__(self, args):
    self.clean = args.clean
    self.cloud = args.cloud
    self.enable_chrome_android_internal = args.enable_chrome_android_internal
    self.extra_gn_args_str = args.gn_args
    self.apply_patch = args.extra_rev
    self.max_jobs = args.max_jobs
    self.max_load_average = args.max_load_average
    self.output_directory = args.output_directory
    self.target = args.target
    self.target_os = args.target_os
    self.use_goma = args.use_goma
    self._SetDefaults()

  @property
  def abs_apk_path(self):
    return os.path.join(self.output_directory, self.apk_path)

  @property
  def apk_name(self):
    # Only works on apk targets that follow: my_great_apk naming convention.
    apk_name = ''.join(s.title() for s in self.target.split('_')[:-1]) + '.apk'
    return apk_name.replace('Webview', 'WebView')

  @property
  def apk_path(self):
    return os.path.join('apks', self.apk_name)

  @property
  def main_lib_path(self):
    # TODO(estevenson): Get this from GN instead of hardcoding.
    if self.IsLinux():
      return 'chrome'
    elif 'monochrome' in self.target:
      return 'lib.unstripped/libmonochrome.so'
    else:
      return 'lib.unstripped/libchrome.so'

  @property
  def abs_main_lib_path(self):
    return os.path.join(self.output_directory, self.main_lib_path)

  @property
  def builder_url(self):
    url = 'https://build.chromium.org/p/chromium.perf/builders/%s%%20Builder'
    return url % self.target_os.title()

  @property
  def download_bucket(self):
    return 'gs://chrome-perf/%s Builder/' % self.target_os.title()

  @property
  def map_file_path(self):
    return self.main_lib_path + '.map.gz'

  @property
  def size_name(self):
    if self.IsLinux():
      return os.path.basename(self.main_lib_path) + '.size'
    return self.apk_name + '.size'

  def _SetDefaults(self):
    has_goma_dir = os.path.exists(os.path.join(os.path.expanduser('~'), 'goma'))
    self.use_goma = self.use_goma or has_goma_dir
    self.max_load_average = (self.max_load_average or
                             str(multiprocessing.cpu_count()))

    has_internal = os.path.exists(
        os.path.join(os.path.dirname(_SRC_ROOT), 'src-internal'))
    if has_internal:
      self.extra_gn_args_str = (
          'is_chrome_branded=true ' + self.extra_gn_args_str)
    else:
      self.extra_gn_args_str = (
          'ffmpeg_branding="Chrome" proprietary_codecs=true' +
          self.extra_gn_args_str)
    if self.IsLinux():
      self.extra_gn_args_str = (
          'is_cfi=false generate_linker_map=true ' + self.extra_gn_args_str)
    self.extra_gn_args_str = ' ' + self.extra_gn_args_str.strip()

    if not self.max_jobs:
      if self.use_goma:
        self.max_jobs = '10000'
      elif has_internal:
        self.max_jobs = '500'
      else:
        self.max_jobs = '50'

    if not self.target:
      if self.IsLinux():
        self.target = 'chrome'
      elif self.enable_chrome_android_internal:
        self.target = 'monochrome_apk'
      else:
        self.target = 'monochrome_public_apk'

  def _GenGnCmd(self):
    gn_args = 'is_official_build=true'
    # Variables often become unused when experimenting with macros to reduce
    # size, so don't fail on warnings.
    gn_args += ' treat_warnings_as_errors=false'
    gn_args += ' use_goma=%s' % str(self.use_goma).lower()
    gn_args += ' target_os="%s"' % self.target_os
    if self.IsAndroid():
      gn_args += (' enable_chrome_android_internal=%s' %
                  str(self.enable_chrome_android_internal).lower())
    gn_args += self.extra_gn_args_str
    return ['gn', 'gen', self.output_directory, '--args=%s' % gn_args]

  def _GenNinjaCmd(self):
    cmd = ['ninja', '-C', self.output_directory]
    cmd += ['-j', self.max_jobs] if self.max_jobs else []
    cmd += ['-l', self.max_load_average] if self.max_load_average else []
    cmd += [self.target]
    return cmd

  def Run(self):
    """Run GN gen/ninja build and return the process returncode."""
    logging.info('Building %s within %s (this might take a while).',
                 self.target, os.path.relpath(self.output_directory))
    if self.clean:
      _RunCmd(['gn', 'clean', self.output_directory])
    retcode = _RunCmd(
        self._GenGnCmd(), verbose=True, exit_on_failure=False)[1]
    if retcode:
      return retcode
    return _RunCmd(
        self._GenNinjaCmd(), verbose=True, exit_on_failure=False)[1]

  def DownloadUrl(self, rev):
    return self.download_bucket + 'full-build-linux_%s.zip' % rev

  def IsAndroid(self):
    return self.target_os == 'android'

  def IsLinux(self):
    return self.target_os == 'linux'

  def IsCloud(self):
    return self.cloud


class _BuildArchive(object):
  """Class for managing a directory with build results and build metadata."""
  def __init__(self, rev, base_archive_dir, build, subrepo, slow_options,
               save_unstripped):
    self.build = build
    self.dir = os.path.join(base_archive_dir, rev)
    metadata_path = os.path.join(self.dir, 'metadata.txt')
    self.rev = rev
    self.metadata = _Metadata([self], build, metadata_path, subrepo)
    self._slow_options = slow_options
    self._save_unstripped = save_unstripped

  def ArchiveBuildResults(self, supersize_path, tool_prefix=None):
    """Save build artifacts necessary for diffing."""
    logging.info('Saving build results to: %s', self.dir)
    _EnsureDirsExist(self.dir)
    if self.build.IsAndroid():
      self._ArchiveFile(self.build.abs_apk_path)
      self._ArchiveFile(self.build.abs_apk_path + '.mapping')
      self._ArchiveResourceSizes()
    self._ArchiveSizeFile(supersize_path, tool_prefix)
    if self._save_unstripped:
      self._ArchiveFile(self.build.abs_main_lib_path)
    self.metadata.Write()
    assert self.Exists()

  def Exists(self):
    ret = self.metadata.Exists() and os.path.exists(self.archived_size_path)
    if self._save_unstripped:
      ret = ret and os.path.exists(self.archived_unstripped_path)
    return ret

  @property
  def archived_unstripped_path(self):
    return os.path.join(self.dir, os.path.basename(self.build.main_lib_path))

  @property
  def archived_size_path(self):
    return os.path.join(self.dir, self.build.size_name)

  def _ArchiveResourceSizes(self):
    cmd = [_RESOURCE_SIZES_PATH, self.build.abs_apk_path,'--output-dir',
           self.dir, '--chartjson']
    if not self.build.IsCloud():
      cmd += ['--chromium-output-dir', self.build.output_directory]
    if self._slow_options:
      cmd += ['--estimate-patch-size', '--dump-static-initializers']
    _RunCmd(cmd)

  def _ArchiveFile(self, filename):
    if not os.path.exists(filename):
      _Die('missing expected file: %s', filename)
    shutil.copy(filename, self.dir)

  def _ArchiveSizeFile(self, supersize_path, tool_prefix):
    existing_size_file = self.build.abs_apk_path + '.size'
    if os.path.exists(existing_size_file):
      logging.info('Found existing .size file')
      shutil.copy(existing_size_file, self.archived_size_path)
    else:
      supersize_cmd = [supersize_path, 'archive', self.archived_size_path,
                       '--elf-file', self.build.abs_main_lib_path]
      if tool_prefix:
        supersize_cmd += ['--tool-prefix', tool_prefix]
      if self.build.IsCloud():
        supersize_cmd += ['--no-source-paths']
      else:
        supersize_cmd += ['--output-directory', self.build.output_directory]
      if self.build.IsAndroid():
        supersize_cmd += ['--apk-file', self.build.abs_apk_path]
      logging.info('Creating .size file')
      _RunCmd(supersize_cmd)


class _DiffArchiveManager(object):
  """Class for maintaining BuildArchives and their related diff artifacts."""
  def __init__(self, revs, archive_dir, diffs, build, subrepo, slow_options,
               save_unstripped):
    self.archive_dir = archive_dir
    self.build = build
    self.build_archives = [
        _BuildArchive(rev, archive_dir, build, subrepo, slow_options,
                      save_unstripped)
        for rev in revs
    ]
    self.diffs = diffs
    self.subrepo = subrepo
    self._summary_stats = []

  def MaybeDiff(self, before_id, after_id):
    """Perform diffs given two build archives."""
    before = self.build_archives[before_id]
    after = self.build_archives[after_id]
    diff_path, short_diff_path = self._DiffFilePaths(before, after)
    if not self._CanDiff(before, after):
      logging.info(
          'Skipping diff for %s due to missing build archives.', diff_path)
      return

    metadata_path = self._DiffMetadataPath(before, after)
    metadata = _Metadata(
        [before, after], self.build, metadata_path, self.subrepo)
    if metadata.Exists():
      logging.info(
          'Skipping diff for %s and %s. Matching diff already exists: %s',
          before.rev, after.rev, diff_path)
    else:
      with open(diff_path, 'w') as diff_file, \
           open(short_diff_path, 'w') as summary_file:
        for d in self.diffs:
          d.RunDiff((diff_file, summary_file), before.dir, after.dir)
      metadata.Write()
      self._AddDiffSummaryStat(before, after)
    if os.path.exists(short_diff_path):
      _PrintFile(short_diff_path)
    logging.info('See detailed diff results here: %s',
                 os.path.relpath(diff_path))

  def Summarize(self):
    path = os.path.join(self.archive_dir, 'last_diff_summary.txt')
    if self._summary_stats:
      with open(path, 'w') as f:
        stats = sorted(
            self._summary_stats, key=lambda x: x[0].value, reverse=True)
        _WriteToFile(f, '\nDiff Summary')
        for s, before, after in stats:
          _WriteToFile(f, '{:>+10} {} {} for range: {}..{}',
                               s.value, s.units, s.name, before, after)
    # Print cached file if all builds were cached.
    if os.path.exists(path):
      _PrintFile(path)
    if self.build_archives and len(self.build_archives) <= 2:
      if not all(a.Exists() for a in self.build_archives):
        return
      supersize_path = os.path.join(_BINARY_SIZE_DIR, 'supersize')
      size2 = ''
      if len(self.build_archives) == 2:
        size2 = os.path.relpath(self.build_archives[-1].archived_size_path)
      logging.info('Enter supersize console via: %s console %s %s',
          os.path.relpath(supersize_path),
          os.path.relpath(self.build_archives[0].archived_size_path), size2)


  def _AddDiffSummaryStat(self, before, after):
    stat = None
    if self.build.IsAndroid():
      summary_diff_type = ResourceSizesDiff
    else:
      summary_diff_type = NativeDiff
    for d in self.diffs:
      if isinstance(d, summary_diff_type):
        stat = d.summary_stat
    if stat:
      self._summary_stats.append((stat, before.rev, after.rev))

  def _CanDiff(self, before, after):
    return before.Exists() and after.Exists()

  def _DiffFilePaths(self, before, after):
    ret = os.path.join(self._DiffDir(before, after), 'diff_results')
    return ret + '.txt', ret + '.short.txt'

  def _DiffMetadataPath(self, before, after):
    return os.path.join(self._DiffDir(before, after), 'metadata.txt')

  def _DiffDir(self, before, after):
    archive_range = '%s..%s' % (before.rev, after.rev)
    diff_path = os.path.join(self.archive_dir, 'diffs', archive_range)
    _EnsureDirsExist(diff_path)
    return diff_path


class _Metadata(object):

  def __init__(self, archives, build, path, subrepo):
    self.is_cloud = build.IsCloud()
    self.data = {
      'revs': [a.rev for a in archives],
      'apply_patch': build.apply_patch,
      'archive_dirs': [a.dir for a in archives],
      'target': build.target,
      'target_os': build.target_os,
      'is_cloud': build.IsCloud(),
      'subrepo': subrepo,
      'path': path,
      'gn_args': {
        'extra_gn_args_str': build.extra_gn_args_str,
        'enable_chrome_android_internal': build.enable_chrome_android_internal,
      }
    }

  def Exists(self):
    path = self.data['path']
    if os.path.exists(path):
      with open(path, 'r') as f:
        return self.data == json.load(f)
    return False

  def Write(self):
    with open(self.data['path'], 'w') as f:
      json.dump(self.data, f)


def _EnsureDirsExist(path):
  if not os.path.exists(path):
    os.makedirs(path)


def _RunCmd(cmd, verbose=False, exit_on_failure=True):
  """Convenience function for running commands.

  Args:
    cmd: the command to run.
    verbose: if this is True, then the stdout and stderr of the process will be
        printed. If it's false, the stdout will be returned.
    exit_on_failure: die if an error occurs when this is True.

  Returns:
    Tuple of (process stdout, process returncode).
  """
  assert not (verbose and exit_on_failure)
  cmd_str = ' '.join(c for c in cmd)
  logging.debug('Running: %s', cmd_str)
  proc_stdout = proc_stderr = subprocess.PIPE
  if verbose:
    proc_stdout, proc_stderr = sys.stdout, subprocess.STDOUT

  proc = subprocess.Popen(cmd, stdout=proc_stdout, stderr=proc_stderr)
  stdout, stderr = proc.communicate()

  if proc.returncode and exit_on_failure:
    _Die('command failed: %s\nstderr:\n%s', cmd_str, stderr)

  stdout = stdout.strip() if stdout else ''
  return stdout, proc.returncode


def _GitCmd(args, subrepo):
  return _RunCmd(['git', '-C', subrepo] + args)[0]


def _GclientSyncCmd(rev, subrepo):
  cwd = os.getcwd()
  os.chdir(subrepo)
  _, retcode = _RunCmd(['gclient', 'sync', '-r', 'src@' + rev],
                       verbose=True, exit_on_failure=False)
  os.chdir(cwd)
  return retcode


def _SyncAndBuild(archive, build, subrepo, no_gclient, extra_rev):
  """Sync, build and return non 0 if any commands failed."""
  # Simply do a checkout if subrepo is used.
  if _CurrentGitHash(subrepo) == archive.rev:
    if subrepo != _SRC_ROOT:
      logging.info('Skipping git checkout since already at desired rev')
    else:
      logging.info('Skipping gclient sync since already at desired rev')
  elif subrepo != _SRC_ROOT or no_gclient:
    _GitCmd(['checkout',  archive.rev], subrepo)
  else:
    # Move to a detached state since gclient sync doesn't work with local
    # commits on a branch.
    _GitCmd(['checkout', '--detach'], subrepo)
    logging.info('Syncing to %s', archive.rev)
    ret = _GclientSyncCmd(archive.rev, subrepo)
    if ret:
      return ret
  with _ApplyPatch(extra_rev, subrepo):
    return build.Run()


@contextmanager
def _ApplyPatch(rev, subrepo):
  if not rev:
    yield
  else:
    restore_func = _GenRestoreFunc(subrepo)
    try:
      _GitCmd(['cherry-pick', rev, '--strategy-option', 'theirs'], subrepo)
      yield
    finally:
      restore_func()


def _GenerateRevList(rev, reference_rev, all_in_range, subrepo, step):
  """Normalize and optionally generate a list of commits in the given range.

  Returns:
    A list of revisions ordered from oldest to newest.
  """
  rev_seq = '%s^..%s' % (reference_rev, rev)
  stdout = _GitCmd(['rev-list', rev_seq], subrepo)
  all_revs = stdout.splitlines()[::-1]
  if all_in_range or len(all_revs) < 2 or step:
    revs = all_revs
    if step:
      revs = revs[::step]
  else:
    revs = [all_revs[0], all_revs[-1]]
  num_revs = len(revs)
  if num_revs >= _COMMIT_COUNT_WARN_THRESHOLD:
    _VerifyUserAccepts(
        'You\'ve provided a commit range that contains %d commits.' % num_revs)
  logging.info('Processing %d commits', num_revs)
  return revs


def _ValidateRevs(rev, reference_rev, subrepo, extra_rev):
  def git_fatal(args, message):
    devnull = open(os.devnull, 'wb')
    retcode = subprocess.call(
        ['git', '-C', subrepo] + args, stdout=devnull, stderr=subprocess.STDOUT)
    if retcode:
      _Die(message)

  no_obj_message = ('%s either doesn\'t exist or your local repo is out of '
                    'date, try "git fetch origin master"')
  git_fatal(['cat-file', '-e', rev], no_obj_message % rev)
  git_fatal(['cat-file', '-e', reference_rev], no_obj_message % reference_rev)
  if extra_rev:
    git_fatal(['cat-file', '-e', extra_rev], no_obj_message % extra_rev)
  git_fatal(['merge-base', '--is-ancestor', reference_rev, rev],
            'reference-rev is newer than rev')


def _VerifyUserAccepts(message):
  print message + ' Do you want to proceed? [y/n]'
  if raw_input('> ').lower() != 'y':
    sys.exit()


def _EnsureDirectoryClean(subrepo):
  logging.info('Checking source directory')
  stdout = _GitCmd(['status', '--porcelain'], subrepo)
  # Ignore untracked files.
  if stdout and stdout[:2] != '??':
    logging.error('Failure: please ensure working directory is clean.')
    sys.exit()


def _Die(s, *args):
  logging.error('Failure: ' + s, *args)
  sys.exit(1)


def _DownloadBuildArtifacts(archive, build, supersize_path, depot_tools_path):
  """Download artifacts from arm32 chromium perf builder."""
  if depot_tools_path:
    gsutil_path = os.path.join(depot_tools_path, 'gsutil.py')
  else:
    gsutil_path = distutils.spawn.find_executable('gsutil.py')

  if not gsutil_path:
    _Die('gsutil.py not found, please provide path to depot_tools via '
         '--depot-tools-path or add it to your PATH')

  download_dir = tempfile.mkdtemp(dir=_SRC_ROOT)
  try:
    _DownloadAndArchive(
        gsutil_path, archive, download_dir, build, supersize_path)
  finally:
    shutil.rmtree(download_dir)


def _DownloadAndArchive(gsutil_path, archive, dl_dir, build, supersize_path):
  # Wraps gsutil calls and returns stdout + stderr.
  def gsutil_cmd(args, fail_msg=None):
    fail_msg = fail_msg or ''
    proc = subprocess.Popen([gsutil_path] + args, stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT)
    output = proc.communicate()[0].rstrip()
    if proc.returncode or not output:
      _Die(fail_msg + ' Process output:\n%s' % output)
    return output

  # Fails if gsutil isn't configured.
  gsutil_cmd(['version'],
             'gsutil error. Please file a bug in Tools>BinarySize.')
  dl_dst = os.path.join(dl_dir, archive.rev)
  logging.info('Downloading build artifacts for %s', archive.rev)

  # Fails if archive isn't found.
  output = gsutil_cmd(['stat', build.DownloadUrl(archive.rev)],
      'Unexpected error while downloading %s. It may no longer exist on the '
      'server or it may not have been uploaded yet (check %s). Otherwise, you '
      'may not have the correct access permissions.' % (
      build.DownloadUrl(archive.rev), build.builder_url))
  size = re.search(r'Content-Length:\s+([0-9]+)', output).group(1)
  logging.info('File size: %s', _ReadableBytes(int(size)))

  # Download archive. Any failures here are unexpected.
  gsutil_cmd(['cp', build.DownloadUrl(archive.rev), dl_dst])

  # Files needed for supersize and resource_sizes. Paths relative to out dir.
  to_extract = [build.main_lib_path, build.map_file_path, 'args.gn']
  if build.IsAndroid():
    to_extract += ['build_vars.txt', build.apk_path,
                   build.apk_path + '.mapping', build.apk_path + '.size']
  extract_dir = dl_dst + '_' + 'unzipped'
  logging.info('Extracting build artifacts')
  with zipfile.ZipFile(dl_dst, 'r') as z:
    dl_out = _ExtractFiles(to_extract, extract_dir, z)
    build.output_directory, output_directory = dl_out, build.output_directory
    archive.ArchiveBuildResults(supersize_path)
    build.output_directory = output_directory


def _ReadableBytes(b):
  val = b
  units = ['Bytes','KB', 'MB', 'GB']
  for unit in units:
    if val < 1024:
      return '%.2f %s' % (val, unit)
    val /= 1024.0
  else:
    return '%d %s' % (b, 'Bytes')


def _ExtractFiles(to_extract, dst, z):
  """Extract a list of files. Returns the common prefix of the extracted files.

  Paths in |to_extract| should be relative to the output directory.
  """
  zipped_paths = z.namelist()
  output_dir = os.path.commonprefix(zipped_paths)
  for f in to_extract:
    path = os.path.join(output_dir, f)
    if path in zipped_paths:
      z.extract(path, path=dst)
  return os.path.join(dst, output_dir)


def _WriteToFile(logfile, s, *args, **kwargs):
  if isinstance(s, basestring):
    data = s.format(*args, **kwargs) + '\n'
  else:
    data = '\n'.join(s) + '\n'
  logfile.write(data)


def _PrintFile(path):
  with open(path) as f:
    sys.stdout.write(f.read())


@contextmanager
def _TmpCopyBinarySizeDir():
  """Recursively copy files to a temp dir and yield temp paths."""
  # Needs to be at same level of nesting as the real //tools/binary_size
  # since supersize uses this to find d3 in //third_party.
  tmp_dir = tempfile.mkdtemp(dir=_SRC_ROOT)
  try:
    bs_dir = os.path.join(tmp_dir, 'binary_size')
    shutil.copytree(_BINARY_SIZE_DIR, bs_dir)
    # We also copy the tools supersize needs, but only if they exist.
    tool_prefix = None
    if os.path.exists(_DOWNLOAD_OBJDUMP_PATH):
      if not os.path.exists(os.path.join(_LLVM_TOOLS_DIR, 'llvm-readelf')):
        _RunCmd([_DOWNLOAD_OBJDUMP_PATH])
      tools_dir = os.path.join(bs_dir, 'bintools')
      tool_prefix = os.path.join(tools_dir, 'llvm-')
      shutil.copytree(_LLVM_TOOLS_DIR, tools_dir)
    yield (os.path.join(bs_dir, 'supersize'), tool_prefix)
  finally:
    shutil.rmtree(tmp_dir)


def _CurrentGitHash(subrepo):
  return _GitCmd(['rev-parse', 'HEAD'], subrepo)


def _GenRestoreFunc(subrepo):
  branch = _GitCmd(['rev-parse', '--abbrev-ref', 'HEAD'], subrepo)
  # Happens when the repo didn't start on a named branch.
  if branch == 'HEAD':
    branch = _GitCmd(['rev-parse', 'HEAD'], subrepo)
  def _RestoreFunc():
    logging.warning('Restoring original git checkout')
    _GitCmd(['checkout', branch], subrepo)
  return _RestoreFunc


def _SetRestoreFunc(subrepo):
  atexit.register(_GenRestoreFunc(subrepo))


def main():
  parser = argparse.ArgumentParser(
      description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument('rev',
                      help='Find binary size bloat for this commit.')
  parser.add_argument('--archive-directory',
                      default=_DEFAULT_ARCHIVE_DIR,
                      help='Where results are stored.')
  parser.add_argument('--reference-rev',
                      help='Older rev to diff against. If not supplied, '
                           'the previous commit to rev will be used.')
  parser.add_argument('--all',
                      action='store_true',
                      help='Build/download all revs from --reference-rev to '
                           'rev and diff the contiguous revisions.')
  parser.add_argument('--include-slow-options',
                      action='store_true',
                      help='Run some extra steps that take longer to complete. '
                           'This includes apk-patch-size estimation and '
                           'static-initializer counting.')
  parser.add_argument('--cloud',
                      action='store_true',
                      help='Download build artifacts from perf builders '
                      '(Googlers only).')
  parser.add_argument('--single',
                      action='store_true',
                      help='Sets --reference-rev=rev.')
  parser.add_argument('--unstripped',
                      action='store_true',
                      help='Save the unstripped native library when archiving.')
  parser.add_argument('--depot-tools-path',
                      help='Custom path to depot tools. Needed for --cloud if '
                           'depot tools isn\'t in your PATH.')
  parser.add_argument('--subrepo',
                      help='Specify a subrepo directory to use. Implies '
                           '--no-gclient. All git commands will be executed '
                           'from the subrepo directory. Does not work with '
                           '--cloud.')
  parser.add_argument('--no-gclient',
                      action='store_true',
                      help='Do not perform gclient sync steps.')
  parser.add_argument('--apply-patch', dest='extra_rev',
                      help='A local commit to cherry-pick before each build. '
                           'This can leave your repo in a broken state if '
                           'the cherry-pick fails.')
  parser.add_argument('--step', type=int,
                      help='Assumes --all and only builds/downloads every '
                           '--step\'th revision.')
  parser.add_argument('-v',
                      '--verbose',
                      action='store_true',
                      help='Show commands executed, extra debugging output'
                           ', and Ninja/GN output.')

  build_group = parser.add_argument_group('build arguments')
  build_group.add_argument('-j',
                           dest='max_jobs',
                           help='Run N jobs in parallel.')
  build_group.add_argument('-l',
                           dest='max_load_average',
                           help='Do not start new jobs if the load average is '
                           'greater than N.')
  build_group.add_argument('--no-goma',
                           action='store_false',
                           dest='use_goma',
                           default=True,
                           help='Do not use goma when building with ninja.')
  build_group.add_argument('--clean',
                           action='store_true',
                           help='Do a clean build for each revision.')
  build_group.add_argument('--gn-args',
                           default='',
                           help='Extra GN args to set.')
  build_group.add_argument('--target-os',
                           default='android',
                           choices=['android', 'linux'],
                           help='target_os gn arg. Default: android.')
  build_group.add_argument('--output-directory',
                           default=_DEFAULT_OUT_DIR,
                           help='ninja output directory. '
                                'Default: %s.' % _DEFAULT_OUT_DIR)
  build_group.add_argument('--enable-chrome-android-internal',
                           action='store_true',
                           help='Allow downstream targets to be built.')
  build_group.add_argument('--target',
                           help='GN target to build. Linux default: chrome. '
                                'Android default: monochrome_public_apk or '
                                'monochrome_apk (depending on '
                                '--enable-chrome-android-internal).')
  if len(sys.argv) == 1:
    parser.print_help()
    return 1

  args = parser.parse_args()
  log_level = logging.DEBUG if args.verbose else logging.INFO
  logging.basicConfig(level=log_level,
                      format='%(levelname).1s %(relativeCreated)6d %(message)s')
  build = _BuildHelper(args)
  if build.IsCloud():
    if args.subrepo:
      parser.error('--subrepo doesn\'t work with --cloud')
    if build.IsLinux():
      parser.error('--target-os linux doesn\'t work with --cloud because map '
                   'files aren\'t generated by builders (crbug.com/716209).')
    if args.extra_rev:
      parser.error('--apply-patch doesn\'t work with --cloud')

  subrepo = args.subrepo or _SRC_ROOT
  if not build.IsCloud():
    _EnsureDirectoryClean(subrepo)
    _SetRestoreFunc(subrepo)

  if build.IsLinux():
    _VerifyUserAccepts('Linux diffs have known deficiencies (crbug/717550).')

  reference_rev = args.reference_rev or args.rev + '^'
  if args.single:
    reference_rev = args.rev
  _ValidateRevs(args.rev, reference_rev, subrepo, args.extra_rev)
  revs = _GenerateRevList(args.rev, reference_rev, args.all, subrepo, args.step)
  with _TmpCopyBinarySizeDir() as paths:
    supersize_path, tool_prefix = paths
    diffs = [NativeDiff(build.size_name, supersize_path)]
    if build.IsAndroid():
      diffs +=  [
          ResourceSizesDiff(build.apk_name)
      ]
    diff_mngr = _DiffArchiveManager(revs, args.archive_directory, diffs, build,
                                    subrepo, args.include_slow_options,
                                    args.unstripped)
    consecutive_failures = 0
    for i, archive in enumerate(diff_mngr.build_archives):
      if archive.Exists():
        step = 'download' if build.IsCloud() else 'build'
        logging.info('Found matching metadata for %s, skipping %s step.',
                     archive.rev, step)
      else:
        if build.IsCloud():
          _DownloadBuildArtifacts(
              archive, build, supersize_path, args.depot_tools_path)
        else:
          build_failure = _SyncAndBuild(archive, build, subrepo,
                                        args.no_gclient, args.extra_rev)
          if build_failure:
            logging.info(
                'Build failed for %s, diffs using this rev will be skipped.',
                archive.rev)
            consecutive_failures += 1
            if len(diff_mngr.build_archives) <= 2:
              _Die('Stopping due to build failure.')
            elif consecutive_failures > _ALLOWED_CONSECUTIVE_FAILURES:
              _Die('%d builds failed in a row, last failure was %s.',
                   consecutive_failures, archive.rev)
          else:
            archive.ArchiveBuildResults(supersize_path, tool_prefix)
            consecutive_failures = 0

      if i != 0:
        diff_mngr.MaybeDiff(i - 1, i)

    diff_mngr.Summarize()


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

