#!/usr/bin/env python
# Copyright (c) 2017, 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 os
import subprocess
import sys
import utils

DEFAULT_TEST = 'org.apache.harmony.jpda.tests.share.AllTests'

TEST_RUNNER = 'org.junit.runner.JUnitCore'
TEST_PACKAGE = 'org.apache.harmony.jpda.tests.jdwp'

VERSIONS = [
  'default',
  '10.0.0',
  '9.0.0',
  '8.1.0',
  '7.0.0',
  '6.0.1',
  '5.1.1',
  '4.4.4'
]

JUNIT_HOSTDEX = os.path.join(
  utils.REPO_ROOT,
  'third_party', 'jdwp-tests', 'junit-hostdex.jar')

JDWP_TESTS_HOSTDEX = os.path.join(
  utils.REPO_ROOT,
  'third_party', 'jdwp-tests', 'apache-harmony-jdwp-tests-hostdex.jar')

IMAGE='/system/non/existent/jdwp/image.art'

# Timeout in ms
TIMEOUT=10000

DEBUGGER_EXTRA_FLAGS = [
  '-Xjnigreflimit:2000',
  '-Duser.language=en',
  '-Duser.region=US',
  '-Djpda.settings.verbose=true',
  '-Djpda.settings.transportAddress=127.0.0.1:55107',
  '-Djpda.settings.timeout=%d' % TIMEOUT,
  '-Djpda.settings.waitingTime=%d' % TIMEOUT
]

DEBUGGEE_EXTRA_FLAGS = [
]

def get_art_dir(version):
  if version == '4.4.4':
    art_dir = 'dalvik'
  else:
    art_dir = version == 'default' and 'art' or 'art-%s' % version
  return os.path.join(utils.REPO_ROOT, 'tools', 'linux', art_dir)

def get_lib_dir(version):
  return os.path.join(get_art_dir(version), 'lib')

def get_fw_dir(version):
  return os.path.join(get_art_dir(version), 'framework')

def get_vm(version):
  return os.path.join(get_art_dir(version), 'bin', 'dalvikvm')

def setup_environment(version):
  art_dir = get_art_dir(version)
  lib_dir = get_lib_dir(version)
  android_data = os.path.join(utils.REPO_ROOT, 'build', 'tmp', version)
  if not os.path.isdir(android_data):
    os.mkdir(android_data)
  if version == '4.4.4':
    # Dalvik expects that the dalvik-cache dir already exists.
    dalvik_cache_dir = os.path.join(android_data, 'dalvik-cache')
    if not os.path.isdir(dalvik_cache_dir):
      os.mkdir(dalvik_cache_dir)
  os.environ['ANDROID_DATA'] = android_data
  os.environ['ANDROID_ROOT'] = art_dir
  os.environ['LD_LIBRARY_PATH'] = lib_dir
  os.environ['DYLD_LIBRARY_PATH'] = lib_dir
  os.environ['LD_USE_LOAD_BIAS'] = '1'

def get_boot_libs(version):
  boot_libs = []
  if version == '4.4.4':
    # Dalvik
    boot_libs.extend(['core-hostdex.jar'])
  else:
    # ART
    boot_libs.extend(['core-libart-hostdex.jar'])
    if version != '5.1.1' and version != '6.0.1':
      boot_libs.extend(['core-oj-hostdex.jar'])
  boot_libs.extend(['apache-xml-hostdex.jar'])
  return [os.path.join(get_fw_dir(version), lib) for lib in boot_libs]

def get_common_flags(version):
  flags = []
  flags.extend(['-Xbootclasspath:%s' % ':'.join(get_boot_libs(version))])
  if version != '4.4.4':
    flags.extend(['-Ximage:%s' % IMAGE])
    if version != '5.1.1':
      flags.extend(['-Xcompiler-option', '--debuggable'])
  if version == '9.0.0' or version == '10.0.0':
    flags.extend(['-XjdwpProvider:internal'])
  return flags

def get_debuggee_flags(version):
  return get_common_flags(version) + DEBUGGEE_EXTRA_FLAGS

def get_debugger_flags(version):
  return get_common_flags(version) + DEBUGGER_EXTRA_FLAGS

def runDebuggee(version, args):
  art_dir = get_art_dir(version)
  lib_dir = get_lib_dir(version)
  fw_dir = get_fw_dir(version)
  cmd = [get_vm(version)]
  cmd.extend(get_debuggee_flags(version))
  cmd.extend(args)
  setup_environment(version)
  print "Running debuggee as:", cmd
  return subprocess.check_call(cmd)

def runDebugger(version, classpath, args):
  art_dir = get_art_dir(version)
  lib_dir = get_lib_dir(version)
  fw_dir = get_fw_dir(version)
  dalvikvm = os.path.join(art_dir, 'bin', 'dalvikvm')
  cmd = [dalvikvm]
  cmd.extend(['-classpath', '%s:%s' % (classpath, JUNIT_HOSTDEX)])
  cmd.extend(get_debugger_flags(version))
  cmd.append('-Djpda.settings.debuggeeJavaPath=%s %s' %\
             (dalvikvm, ' '.join(get_debuggee_flags(version))))
  cmd.extend(args)
  setup_environment(version)
  print "Running debugger as:", cmd
  return subprocess.check_call(cmd)

def usage():
  print "Usage: %s [--debuggee] [--version=<version>] [--classpath=<classpath>] <args>" % (sys.argv[0])
  print "where <version> is one of:", ', '.join(VERSIONS)
  print "  and <classpath> is optional classpath (default: %s)" % JDWP_TESTS_HOSTDEX
  print "  and <args> will be passed on as arguments to the art runtime."

def main():
  version = 'default'
  debuggee = False
  args = []
  classpath = JDWP_TESTS_HOSTDEX
  for arg in sys.argv[1:]:
    if arg == '--help':
      usage()
      return 0
    elif arg.startswith('--version='):
      version = arg[len('--version='):]
    elif arg.startswith('--classpath='):
      classpath = arg[len('--classpath='):]
    else:
      args.append(arg)
  if version not in VERSIONS:
    print "Invalid version", version
    usage()
    return 1
  if not debuggee and len(args) == 0:
    args.append(DEFAULT_TEST)
  if debuggee:
    return runDebuggee(version, args)
  else:
    if len(args) == 0:
      args.append(DEFAULT_TEST)
    elif len(args) == 1:
      args = [TEST_RUNNER, args[0]]
    return runDebugger(version, classpath, args)

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