#!/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
    if get_hash_from_map_file(utils.R8LIB_MAP) == maphash:
      return utils.R8LIB_MAP

    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_MAP


def check_maphash(mapping_path, maphash, args):
  infile_maphash = get_hash_from_map_file(mapping_path)
  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 get_hash_from_map_file(mapping_path):
  map_hash_header = "# pg_map_hash: SHA-256 "
  for line in open(mapping_path, 'r'):
    if line.startswith(map_hash_header):
      return line[len(map_hash_header):].strip()

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())
