# 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 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.run_gradle([
            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, 0)
        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
