# Copyright (c) 2018, 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 glob
import subprocess
from threading import Timer

import gradle
import jdk
import utils


def run(tool, args, build=None, debug=True,
        profile=False, track_memory_file=None, extra_args=None,
        stderr=None, stdout=None, return_stdout=False, timeout=0, quiet=False,
        cmd_prefix=None, jar=None, main=None):
  cmd = []
  if cmd_prefix:
    cmd.extend(cmd_prefix)
  if build is None:
    build, args = extract_build_from_args(args)
  if build:
    gradle.RunGradle(['r8lib' if tool.startswith('r8lib') else 'r8'])
  if track_memory_file:
    cmd.extend(['tools/track_memory.sh', track_memory_file])
  cmd.append(jdk.GetJavaExecutable())
  if extra_args:
    cmd.extend(extra_args)
  if debug:
    cmd.append('-ea')
  if profile:
    cmd.append('-agentlib:hprof=cpu=samples,interval=1,depth=8')
  if jar:
    cmd.extend(['-cp', jar, main])
  elif tool == 'r8lib-d8':
    cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.D8'])
  elif tool == 'r8lib-r8':
    cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.R8'])
  else:
    cmd.extend(['-jar', utils.R8_JAR, tool])
  lib, args = extract_lib_from_args(args)
  if lib:
    cmd.extend(["--lib", lib])
  cmd.extend(args)
  utils.PrintCmd(cmd, quiet=quiet)
  if timeout > 0:
    kill = lambda process: process.kill()
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    timer = Timer(timeout, kill, [proc])
    try:
      timer.start()
      stdout, stderr = proc.communicate()
    finally:
      timer.cancel()
    return stdout if return_stdout else proc.returncode
  else:
    if return_stdout:
      return subprocess.check_output(cmd)
    return subprocess.call(cmd, stdout=stdout, stderr=stderr)

def run_in_tests(tool, args, build=None, debug=True, extra_args=None):
  if build is None:
    build, args = extract_build_from_args(args)
  if build:
    gradle.RunGradle([
      'copyMavenDeps',
      'compileTestJava',
    ])
  cmd = []
  cmd.append(jdk.GetJavaExecutable())
  if extra_args:
    cmd.extend(extra_args)
  if debug:
    cmd.append('-ea')
  cmd.extend(['-cp', ':'.join([
    utils.BUILD_MAIN_DIR,
    utils.BUILD_TEST_DIR,
  ] + glob.glob('%s/*.jar' % utils.BUILD_DEPS_DIR))])
  cmd.extend([tool])
  cmd.extend(args)
  utils.PrintCmd(cmd)
  return subprocess.call(cmd)

def extract_build_from_args(input_args):
  build = True
  args = []
  for arg in input_args:
    if arg in ("--build", "--no-build"):
      build = arg == "--build"
    else:
      args.append(arg)
  return build, args

def extract_lib_from_args(input_args):
  lib = None
  args = []
  for arg in input_args:
    if arg == '--lib-android':
      lib = utils.get_android_jar(28)
    elif arg == '--lib-java':
      lib = utils.RT_JAR
    else:
      args.append(arg)
  return lib, args
