#!/usr/bin/env python3
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Generate a size report for target binaries.

For example:
$ tools/ninja -C out/r traced_probes traced
$ tools/size-report.py -C out/r traced_probes traced
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import os
import subprocess
import sys
import json

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BLOATY_PATH = os.path.join(ROOT_DIR, 'buildtools', 'bloaty', 'bloaty')
GN_PATH = os.path.join(ROOT_DIR, 'tools', 'gn')

def GetGnArgValueOrNone(arg):
  if 'current' in arg:
    return eval(arg['current']['value'])
  if 'default' in arg:
    return eval(arg['default']['value'])
  return None


def GetTargetOsForBuildDir(build_dir):
  cmd = [GN_PATH, 'args', '--list', '--json', build_dir]
  args = json.loads(subprocess.check_output(cmd))
  target_os = None
  host_os = None
  for arg in args:
    if arg['name'] == 'target_os':
      print(arg)
      target_os = GetGnArgValueOrNone(arg)
    if arg['name'] == 'host_os':
      print(arg)
      host_os = GetGnArgValueOrNone(arg)
  return target_os or host_os or None


def main():
  parser = argparse.ArgumentParser(
      formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__)
  parser.add_argument(
      '-C', '--build-dir', metavar='DIR', help='build directory', required=True)
  parser.add_argument('-o', '--output', help='output path', default=None)
  parser.add_argument(
      'binaries', metavar='BINARY', nargs='+', help='subjects of size report')
  args = parser.parse_args()

  if not os.path.exists(BLOATY_PATH):
    print(
        'Could not find bloaty at expected path "{}". Try re-running ./tools/install-build-deps'
        .format(BLOATY_PATH))
    return 1

  results = []

  out_directory = args.build_dir
  target_os = GetTargetOsForBuildDir(out_directory)
  print('target_os', target_os)
  for binary in args.binaries:
    binary_path = os.path.join(out_directory, binary)
    output = '{} - {}\n'.format(binary, binary_path)
    if target_os == 'mac':
      subprocess.check_output(['dsymutil', binary_path])
      symbols = '--debug-file={}.dSYM/Contents/Resources/DWARF/{}'.format(
          binary_path, binary)
      cmd = [symbols, '-d', 'compileunits', '-n', '100', binary_path]
    else:
      cmd = ['-d', 'compileunits', '-n', '100', binary_path]
    output += subprocess.check_output([BLOATY_PATH] + cmd).decode('utf-8')
    results.append(output)

  if args.output is None or args.output == '-':
    out = sys.stdout
  else:
    out = open(args.output, 'w')

  for result in results:
    out.write(result)
    out.write('\n')
  return 0


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