#!/usr/bin/env python3
# Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import os
import subprocess
import sys

import jdk
import utils


def parse_arguments():
  parser = argparse.ArgumentParser(
      description = 'R8lib wrapper for retrace tool.')
  parser.add_argument(
      '-c',
      '--commit-hash',
      '--commit_hash',
      help='Commit hash to download r8lib map file for.',
      default=None)
  parser.add_argument(
      '--version',
      help='Version to download r8lib map file for.',
      default=None)
  parser.add_argument(
      '--tag',
      help='Tag to download r8lib map file for.',
      default=None)
  parser.add_argument(
      '--exclude-deps', '--exclude_deps',
      default=None,
      action='store_true',
      help='Use the exclude-deps version of the mapping file.')
  parser.add_argument(
      '--map',
      help='Path to r8lib map.',
      default=None)
  parser.add_argument(
      '--no-r8lib',
      '--no_r8lib',
      default=False,
      action='store_true',
      help='Use r8.jar and not r8lib.jar.')
  parser.add_argument(
      '--stacktrace',
      help='Path to stacktrace file (read from stdin if not passed).',
      default=None)
  parser.add_argument(
      '--quiet',
      default=None,
      action='store_true',
      help='Disables diagnostics printing to stdout.')
  parser.add_argument(
      '--debug-agent',
      '--debug_agent',
      default=None,
      action='store_true',
      help='Attach a debug-agent to the retracer java process.')
  parser.add_argument(
      '--regex',
      default=None,
      help='Sets a custom regular expression used for parsing'
  )
  parser.add_argument(
      '--verbose',
      default=None,
      action='store_true',
      help='Enables verbose retracing.')
  parser.add_argument(
      '--disable-map-validation',
      default=None,
      action='store_true',
      help='Disable validation of map hash.')
  return parser.parse_args()


def get_map_file(args, temp):
  # default to using the specified map file.
  if args.map:
    return args.map

  # next try to extract it from the tag/version options.
  map_path = utils.find_cloud_storage_file_from_options('r8lib.jar.map', args)
  if map_path:
    return map_path

  # next try to extract it from the stack-trace source-file content.
  if not args.stacktrace:
    if not args.quiet:
      print('Waiting for stack-trace input...')
    args.stacktrace = os.path.join(temp, 'stacktrace.txt')
    open(args.stacktrace, 'w').writelines(sys.stdin.readlines())

  r8_source_file = None
  for line in open(args.stacktrace, 'r'):
    start = line.rfind("(R8_")
    if start > 0:
      end = line.find(":", start)
      content = line[start + 1: end]
      if r8_source_file:
        if content != r8_source_file:
          print('WARNING: there are multiple distinct R8 source files:')
          print(' ' + r8_source_file)
          print(' ' + content)
      else:
        r8_source_file = content

  if r8_source_file:
    (header, r8_version_or_hash, maphash) = r8_source_file.split('_')
    # If the command-line specified --exclude-deps then assume it is as previous
    # versions will not be marked as such in the source-file line.
    is_excldeps = args.exclude_deps
    excldeps_start = r8_version_or_hash.find('+excldeps')
    if (excldeps_start > 0):
      is_excldeps = True
      r8_version_or_hash = r8_version_or_hash[0:excldeps_start]
    if len(r8_version_or_hash) < 40:
      args.version = r8_version_or_hash
    else:
      args.commit_hash = r8_version_or_hash
    map_path = None
    try:
      map_path = utils.find_cloud_storage_file_from_options(
        'r8lib' + ('-exclude-deps' if is_excldeps else '') + '.jar.map', args)
    except Exception as e:
      print(e)
      print('WARNING: Falling back to using local mapping file.')

    if map_path and not args.disable_map_validation:
      check_maphash(map_path, maphash, args)
      return map_path

  # If no other map file was found, use the local mapping file.
  return utils.R8LIB_JAR + '.map'


def check_maphash(mapping_path, maphash, args):
  map_hash_header = "# pg_map_hash: SHA-256 "
  for line in open(mapping_path, 'r'):
    if line.startswith(map_hash_header):
      infile_maphash = line[len(map_hash_header):].strip()
      if infile_maphash != maphash:
        print('ERROR: The mapping file hash does not match the R8 line')
        print('  In mapping file: ' + infile_maphash)
        print('  In source file:  ' + maphash)
        if (not args.exclude_deps):
          print('If this could be a version without internalized dependencies '
              + 'try passing --exclude-deps')
        sys.exit(1)


def main():
  args = parse_arguments()
  with utils.TempDir() as temp:
    map_path = get_map_file(args, temp)
    return run(
      map_path,
      args.stacktrace,
      args.no_r8lib,
      quiet=args.quiet,
      debug=args.debug_agent,
      regex=args.regex,
      verbose=args.verbose)


def run(map_path, stacktrace, no_r8lib, quiet=False, debug=False, regex=None, verbose=False):
  retrace_args = [jdk.GetJavaExecutable()]

  if debug:
    retrace_args.append(
        '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005')

  retrace_args += [
    '-cp',
    utils.R8_JAR if no_r8lib else utils.R8RETRACE_JAR,
    'com.android.tools.r8.retrace.Retrace',
    map_path
  ]

  if regex:
    retrace_args.append('--regex')
    retrace_args.append(regex)

  if quiet:
    retrace_args.append('--quiet')

  if stacktrace:
    retrace_args.append(stacktrace)

  if verbose:
    retrace_args.append('--verbose')

  utils.PrintCmd(retrace_args, quiet=quiet)
  return subprocess.call(retrace_args)


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