# 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,
        disable_assertions=False,
        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 not disable_assertions:
        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(['-cp', utils.R8_JAR, 'com.android.tools.r8.SwissArmyKnife', 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
