"""
If the build* function is passed the compiler argument, for example, 'llvm-gcc',
it is passed as a make variable to the make command.  Otherwise, we check the
LLDB_CC environment variable; if it is defined, it is passed as a make variable
to the make command.

If neither the compiler keyword argument nor the LLDB_CC environment variable is
specified, no CC make variable is passed to the make command.  The Makefile gets
to define the default CC being used.

Same idea holds for LLDB_ARCH environment variable, which maps to the ARCH make
variable.
"""

# System imports
import os
import platform
import subprocess
import sys

# Our imports
import lldbsuite.test.lldbtest as lldbtest
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test_event import build_exception


def getArchitecture():
    """Returns the architecture in effect the test suite is running with."""
    return os.environ["ARCH"] if "ARCH" in os.environ else ""


def getCompiler():
    """Returns the compiler in effect the test suite is running with."""
    compiler = os.environ.get("CC", "clang")
    compiler = lldbutil.which(compiler)
    return os.path.realpath(compiler)


def getArchFlag():
    """Returns the flag required to specify the arch"""
    compiler = getCompiler()
    if compiler is None:
        return ""
    elif "gcc" in compiler:
        archflag = "-m"
    elif "clang" in compiler:
        archflag = "-arch"
    else:
        archflag = None

    return ("ARCHFLAG=" + archflag) if archflag else ""

def getMake(test_subdir, test_name):
    """Returns the invocation for GNU make.
       The first argument is a tuple of the relative path to the testcase
       and its filename stem."""
    if platform.system() == "FreeBSD" or platform.system() == "NetBSD":
        make = "gmake"
    else:
        make = "make"

    # Construct the base make invocation.
    lldb_test = os.environ["LLDB_TEST"]
    lldb_build = os.environ["LLDB_BUILD"]
    if not (lldb_test and lldb_build and test_subdir and test_name and
            (not os.path.isabs(test_subdir))):
        raise Exception("Could not derive test directories")
    build_dir = os.path.join(lldb_build, test_subdir, test_name)
    src_dir = os.path.join(lldb_test, test_subdir)
    # This is a bit of a hack to make inline testcases work.
    makefile = os.path.join(src_dir, "Makefile")
    if not os.path.isfile(makefile):
        makefile = os.path.join(build_dir, "Makefile")
    return [make,
            "VPATH="+src_dir,
            "-C", build_dir,
            "-I", src_dir,
            "-f", makefile]


def getArchSpec(architecture):
    """
    Helper function to return the key-value string to specify the architecture
    used for the make system.
    """
    arch = architecture if architecture else None
    if not arch and "ARCH" in os.environ:
        arch = os.environ["ARCH"]

    return ("ARCH=" + arch) if arch else ""


def getCCSpec(compiler):
    """
    Helper function to return the key-value string to specify the compiler
    used for the make system.
    """
    cc = compiler if compiler else None
    if not cc and "CC" in os.environ:
        cc = os.environ["CC"]
    if cc:
        return "CC=\"%s\"" % cc
    else:
        return ""


def getCmdLine(d):
    """
    Helper function to return a properly formatted command line argument(s)
    string used for the make system.
    """

    # If d is None or an empty mapping, just return an empty string.
    if not d:
        return ""
    pattern = '%s="%s"' if "win32" in sys.platform else "%s='%s'"

    def setOrAppendVariable(k, v):
        append_vars = ["CFLAGS_EXTRAS", "LD_EXTRAS"]
        if k in append_vars and k in os.environ:
            v = os.environ[k] + " " + v
        return pattern % (k, v)
    cmdline = " ".join([setOrAppendVariable(k, v) for k, v in list(d.items())])

    return cmdline


def runBuildCommands(commands, sender):
    try:
        lldbtest.system(commands, sender=sender)
    except subprocess.CalledProcessError as called_process_error:
        # Convert to a build-specific error.
        # We don't do that in lldbtest.system() since that
        # is more general purpose.
        raise build_exception.BuildError(called_process_error)


def buildDefault(
        sender=None,
        architecture=None,
        compiler=None,
        dictionary=None,
        testdir=None,
        testname=None):
    """Build the binaries the default way."""
    commands = []
    commands.append(getMake(testdir, testname) + ["all", getArchSpec(architecture),
                     getCCSpec(compiler), getCmdLine(dictionary)])

    runBuildCommands(commands, sender=sender)

    # True signifies that we can handle building default.
    return True


def buildDwarf(
        sender=None,
        architecture=None,
        compiler=None,
        dictionary=None,
        testdir=None,
        testname=None):
    """Build the binaries with dwarf debug info."""
    commands = []
    commands.append(getMake(testdir, testname) +
                    ["MAKE_DSYM=NO", getArchSpec(architecture),
                     getCCSpec(compiler), getCmdLine(dictionary)])

    runBuildCommands(commands, sender=sender)
    # True signifies that we can handle building dwarf.
    return True


def buildDwo(
        sender=None,
        architecture=None,
        compiler=None,
        dictionary=None,
        testdir=None,
        testname=None):
    """Build the binaries with dwarf debug info."""
    commands = []
    commands.append(getMake(testdir, testname) +
                    ["MAKE_DSYM=NO", "MAKE_DWO=YES",
                     getArchSpec(architecture),
                     getCCSpec(compiler),
                     getCmdLine(dictionary)])

    runBuildCommands(commands, sender=sender)
    # True signifies that we can handle building dwo.
    return True


def buildGModules(
        sender=None,
        architecture=None,
        compiler=None,
        dictionary=None,
        testdir=None,
        testname=None):
    """Build the binaries with dwarf debug info."""
    commands = []
    commands.append(getMake(testdir, testname) +
                    ["MAKE_DSYM=NO",
                     "MAKE_GMODULES=YES",
                     getArchSpec(architecture),
                     getCCSpec(compiler),
                     getCmdLine(dictionary)])

    lldbtest.system(commands, sender=sender)
    # True signifies that we can handle building with gmodules.
    return True


def cleanup(sender=None, dictionary=None):
    """Perform a platform-specific cleanup after the test."""
    return True
