# 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(['-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
