# 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 time
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, time_consumer=None,
        debug_agent=None, worker_id=None):
  cmd = []
  if cmd_prefix:
    cmd.extend(cmd_prefix)
  if build is None:
    build, args = extract_build_from_args(args)
  if build:
    gradle.RunGradle([
        utils.GRADLE_TASK_R8LIB if tool.startswith('r8lib')
        else utils.GRADLE_TASK_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_agent is None:
    debug_agent, args = extract_debug_agent_from_args(args)
  if debug_agent:
    cmd.append(
        '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005')
  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-l8':
    cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.L8'])
  elif tool == 'r8lib-r8':
    cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.R8'])
  elif tool == 'r8lib-tracereferences':
    cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.tracereferences.TraceReferences'])
  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, worker_id=worker_id)
  start = time.time()
  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()
    result = stdout.decode('utf-8') if return_stdout else proc.returncode
  else:
    result = (
        subprocess.check_output(cmd).decode('utf-8')
        if return_stdout
        else subprocess.call(cmd, stdout=stdout, stderr=stderr))
  duration = int((time.time() - start) * 1000)
  if time_consumer:
    time_consumer(duration)
  return result

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

def extract_debug_agent_from_args(input_args):
  agent = False
  args = []
  for arg in input_args:
    if arg in ('--debug-agent', '--debug_agent'):
      agent = True
    else:
      args.append(arg)
  return agent, args
