#!/usr/bin/env python3
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Reports binary size metrics for LaCrOS build artifacts.

More information at //docs/speed/binary_size/metrics.md.
"""

import argparse
import collections
import contextlib
import json
import logging
import os
import subprocess
import sys
import tempfile
SRC_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
sys.path.insert(0, os.path.join(SRC_DIR, 'build', 'util'))
from lib.results import result_sink
from lib.results import result_types


@contextlib.contextmanager
def _SysPath(path):
  """Library import context that temporarily appends |path| to |sys.path|."""
  if path and path not in sys.path:
    sys.path.insert(0, path)
  else:
    path = None  # Indicates that |sys.path| is not modified.
  try:
    yield
  finally:
    if path:
      sys.path.pop(0)


DIR_SOURCE_ROOT = os.environ.get(
    'CHECKOUT_SOURCE_ROOT',
    os.path.abspath(
        os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)))

BUILD_COMMON_PATH = os.path.join(DIR_SOURCE_ROOT, 'build', 'util', 'lib',
                                 'common')

TRACING_PATH = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'catapult',
                            'tracing')

EU_STRIP_PATH = os.path.join(DIR_SOURCE_ROOT, 'buildtools', 'third_party',
                             'eu-strip', 'bin', 'eu-strip')

with _SysPath(BUILD_COMMON_PATH):
  import perf_tests_results_helper  # pylint: disable=import-error

with _SysPath(TRACING_PATH):
  from tracing.value import convert_chart_json  # pylint: disable=import-error

_BASE_CHART = {
    'format_version': '0.1',
    'benchmark_name': 'resource_sizes',
    'trace_rerun_options': [],
    'charts': {}
}

_KEY_RAW = 'raw'
_KEY_GZIPPED = 'gzipped'
_KEY_STRIPPED = 'stripped'
_KEY_STRIPPED_GZIPPED = 'stripped_then_gzipped'


class _Group:
  """A group of build artifacts whose file sizes are summed and tracked.

  Build artifacts for size tracking fall under these categories:
  * File: A single file.
  * Group: A collection of files.
  * Dir: All files under a directory.

  Attributes:
    paths: A list of files or directories to be tracked together.
    title: The display name of the group.
    track_stripped: Whether to also track summed stripped ELF sizes.
    track_compressed: Whether to also track summed compressed sizes.
  """

  def __init__(self, paths, title, track_stripped=False,
               track_compressed=False):
    self.paths = paths
    self.title = title
    self.track_stripped = track_stripped
    self.track_compressed = track_compressed

  def __eq__(self, other):
    """Overrides the default implementation"""
    if isinstance(other, _Group):
      return (self.paths == other.paths) & (self.title == other.title) & (
          self.track_stripped == other.track_stripped) & (
              self.track_compressed == other.track_compressed)
    return False

# Common artifacts in official builder lacros-arm32 and lacros64 in
# src-internal. The artifcts can be found in
# chromium/src-internal/testing/buildbot/archive/lacros64.json and
# chromium/src-internal/testing/buildbot/archive/lacros-arm32.json
# chromium/src-internal/testing/buildbot/archive/lacros-arm64.json
_TRACKED_GROUPS = [
    _Group(paths=['chrome'],
           title='File: chrome',
           track_stripped=True,
           track_compressed=True),
    _Group(paths=['chrome_crashpad_handler'],
           title='File: chrome_crashpad_handler'),
    _Group(paths=['icudtl.dat'], title='File: icudtl.dat'),
    _Group(paths=['icudtl.dat.hash'], title='File: icudtl.dat.hash'),
    _Group(paths=['libEGL.so'], title='File: libEGL.so'),
    _Group(paths=['libGLESv2.so'], title='File: libGLESv2.so'),
    _Group(paths=['nacl_helper'], title='File: nacl_helper'),
    _Group(paths=['resources.pak'], title='File: resources.pak'),
    _Group(paths=[
        'chrome_100_percent.pak', 'chrome_200_percent.pak',
        'headless_lib_data.pak', 'headless_lib_strings.pak'
    ],
           title='Group: Other PAKs'),
    _Group(paths=['snapshot_blob.bin'], title='Group: Misc'),
    _Group(paths=['locales/'], title='Dir: locales'),
    _Group(paths=['WidevineCdm/'], title='Dir: WidevineCdm'),
]


def _visit_paths(base_dir, paths):
  """Itemizes files specified by a list of paths.

  Args:
    base_dir: Base directory for all elements in |paths|.
    paths: A list of filenames or directory names to specify files whose sizes
      to be counted. Directories are recursed. There's no de-duping effort.
      Non-existing files or directories are ignored (with warning message).
  """
  for path in paths:
    full_path = os.path.join(base_dir, path)
    if os.path.exists(full_path):
      if os.path.isdir(full_path):
        for dirpath, _, filenames in os.walk(full_path):
          for filename in filenames:
            yield os.path.join(dirpath, filename)
      else:  # Assume is file.
        yield full_path
    else:
      logging.critical('Not found: %s', path)


def _is_probably_elf(filename):
  """Heuristically decides whether |filename| is ELF via magic signature."""
  with open(filename, 'rb') as fh:
    return fh.read(4) == '\x7FELF'


def _is_unstrippable_elf(filename):
  """Identifies known-unstrippable ELF files to denoise the system."""
  return filename.endswith('.nexe') or filename.endswith('libwidevinecdm.so')


def _get_filesize(filename):
  """Returns the size of a file, or 0 if file is not found."""
  try:
    return os.path.getsize(filename)
  except OSError:
    logging.critical('Failed to get size: %s', filename)
  return 0


def _get_gzipped_filesize(filename):
  """Returns the gzipped size of a file, or 0 if file is not found."""
  BUFFER_SIZE = 65536
  if not os.path.isfile(filename):
    return 0
  try:
    # Call gzip externally instead of using gzip package since it's > 2x faster.
    cmd = ['gzip', '-c', filename]
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    # Manually counting bytes instead of using len(p.communicate()[0]) to avoid
    # buffering the entire compressed data (can be ~100 MB).
    ret = 0
    while True:
      chunk = len(p.stdout.read(BUFFER_SIZE))
      if chunk == 0:
        break
      ret += chunk
    return ret
  except OSError:
    logging.critical('Failed to get gzipped size: %s', filename)
  return 0


def _get_catagorized_filesizes(filename):
  """Measures |filename| sizes under various transforms.

  Returns: A Counter (keyed by _Key_* constants) that stores measured sizes.
  """
  sizes = collections.Counter()
  sizes[_KEY_RAW] = _get_filesize(filename)
  sizes[_KEY_GZIPPED] = _get_gzipped_filesize(filename)

  # Pre-assign values for non-ELF, or in case of failure for ELF.
  sizes[_KEY_STRIPPED] = sizes[_KEY_RAW]
  sizes[_KEY_STRIPPED_GZIPPED] = sizes[_KEY_GZIPPED]

  if _is_probably_elf(filename) and not _is_unstrippable_elf(filename):
    try:
      fd, temp_file = tempfile.mkstemp()
      os.close(fd)
      cmd = [EU_STRIP_PATH, filename, '-o', temp_file]
      subprocess.check_output(cmd)
      sizes[_KEY_STRIPPED] = _get_filesize(temp_file)
      sizes[_KEY_STRIPPED_GZIPPED] = _get_gzipped_filesize(temp_file)
      if sizes[_KEY_STRIPPED] > sizes[_KEY_RAW]:
        # This weird case has been observed for libwidevinecdm.so.
        logging.critical('Stripping made things worse for %s' % filename)
    except subprocess.CalledProcessError:
      logging.critical('Failed to strip file: %s' % filename)
    finally:
      os.unlink(temp_file)
  return sizes


def _dump_chart_json(output_dir, chartjson):
  """Writes chart histogram to JSON files.

  Output files:
    results-chart.json contains the chart JSON.
    perf_results.json contains histogram JSON for Catapult.

  Args:
    output_dir: Directory to place the JSON files.
    chartjson: Source JSON data for output files.
  """
  results_path = os.path.join(output_dir, 'results-chart.json')
  logging.critical('Dumping chartjson to %s', results_path)
  with open(results_path, 'w') as json_file:
    json.dump(chartjson, json_file, indent=2)

  # We would ideally generate a histogram set directly instead of generating
  # chartjson then converting. However, perf_tests_results_helper is in
  # //build, which doesn't seem to have any precedent for depending on
  # anything in Catapult. This can probably be fixed, but since this doesn't
  # need to be super fast or anything, converting is a good enough solution
  # for the time being.
  histogram_result = convert_chart_json.ConvertChartJson(results_path)
  if histogram_result.returncode != 0:
    raise Exception('chartjson conversion failed with error: ' +
                    histogram_result.stdout)

  histogram_path = os.path.join(output_dir, 'perf_results.json')
  logging.critical('Dumping histograms to %s', histogram_path)
  with open(histogram_path, 'wb') as json_file:
    json_file.write(histogram_result.stdout)


def _run_resource_sizes(args):
  """Main flow to extract and output size data."""
  chartjson = _BASE_CHART.copy()
  chartjson.update({
      'benchmark_description':
      ('LaCrOS %s resource size information.' % args.arch)
  })
  report_func = perf_tests_results_helper.ReportPerfResult
  total_sizes = collections.Counter()

  def report_sizes(sizes, title, track_stripped, track_compressed):
    report_func(chart_data=chartjson,
                graph_title=title,
                trace_title='size',
                value=sizes[_KEY_RAW],
                units='bytes')

    if track_stripped:
      report_func(chart_data=chartjson,
                  graph_title=title + ' (Stripped)',
                  trace_title='size',
                  value=sizes[_KEY_STRIPPED],
                  units='bytes')

    if track_compressed:
      report_func(chart_data=chartjson,
                  graph_title=title + ' (Gzipped)',
                  trace_title='size',
                  value=sizes[_KEY_GZIPPED],
                  units='bytes')

    if track_stripped and track_compressed:
      report_func(chart_data=chartjson,
                  graph_title=title + ' (Stripped, Gzipped)',
                  trace_title='size',
                  value=sizes[_KEY_STRIPPED_GZIPPED],
                  units='bytes')

  tracked_groups = _TRACKED_GROUPS.copy()
  # Architecture amd64 requires artifact nacl_irt_x86_64.nexe.
  if args.arch == 'amd64':
    tracked_groups.append(
        _Group(paths=['nacl_irt_x86_64.nexe'],
               title='File: nacl_irt_x86_64.nexe'))
  # Architecture arm32 requires artifact nacl_irt_arm.nexe.
  elif args.arch == 'arm32':
    tracked_groups.append(
        _Group(paths=['nacl_irt_arm.nexe'], title='File: nacl_irt_arm.nexe'))
    tracked_groups.append(
        _Group(paths=['nacl_helper_bootstrap'],
               title='File: nacl_helper_bootstrap'))
  # TODO(https://crbug.com/1356761): remove the following part once nacl files
  # are available.
  elif args.arch == 'arm64':
    tracked_groups.remove(
        _Group(paths=['nacl_helper'], title='File: nacl_helper'))
  for g in tracked_groups:
    sizes = sum(
        map(_get_catagorized_filesizes, _visit_paths(args.out_dir, g.paths)),
        collections.Counter())
    report_sizes(sizes, g.title, g.track_stripped, g.track_compressed)

    # Total compressed size is summed over individual compressed sizes, instead
    # of concatanating first, then compress everything. This is done for
    # simplicity. It also gives a conservative size estimate (assuming file
    # metadata and overheads are negligible).
    total_sizes += sizes

  report_sizes(total_sizes, 'Total', True, True)

  _dump_chart_json(args.output_dir, chartjson)


def main():
  """Parses arguments and runs high level flows."""
  argparser = argparse.ArgumentParser(description='Writes LaCrOS size metrics.')

  argparser.add_argument('--chromium-output-directory',
                         dest='out_dir',
                         required=True,
                         type=os.path.realpath,
                         help='Location of the build artifacts.')
  argparser.add_argument('--arch',
                         required=True,
                         type=str,
                         help='The architecture of lacros, valid values: amd64,'
                         ' arm32, arm64')

  output_group = argparser.add_mutually_exclusive_group()

  output_group.add_argument('--output-dir',
                            default='.',
                            help='Directory to save chartjson to.')

  # Accepted to conform to the isolated script interface, but ignored.
  argparser.add_argument('--isolated-script-test-filter',
                         help=argparse.SUPPRESS)
  argparser.add_argument('--isolated-script-test-perf-output',
                         type=os.path.realpath,
                         help=argparse.SUPPRESS)

  output_group.add_argument(
      '--isolated-script-test-output',
      type=os.path.realpath,
      help='File to which results will be written in the simplified JSON '
      'output format.')

  args = argparser.parse_args()

  isolated_script_output = {'valid': False, 'failures': []}
  if args.isolated_script_test_output:
    test_name = 'lacros_resource_sizes'
    args.output_dir = os.path.join(
        os.path.dirname(args.isolated_script_test_output), test_name)
    if not os.path.exists(args.output_dir):
      os.makedirs(args.output_dir)

  try:
    _run_resource_sizes(args)
    isolated_script_output = {'valid': True, 'failures': []}
  finally:
    if args.isolated_script_test_output:
      results_path = os.path.join(args.output_dir, 'test_results.json')
      with open(results_path, 'w') as output_file:
        json.dump(isolated_script_output, output_file)
      with open(args.isolated_script_test_output, 'w') as output_file:
        json.dump(isolated_script_output, output_file)
  result_sink_client = result_sink.TryInitClient()
  if result_sink_client:
    status = result_types.PASS
    if not isolated_script_output['valid']:
      status = result_types.UNKNOWN
    elif isolated_script_output['failures']:
      status = result_types.FAIL
    result_sink_client.Post(test_name, status, None, None, None)


if __name__ == '__main__':
  main()
