import os
import platform
import subprocess
import sys
import itertools

import lldbsuite.test.lldbtest as lldbtest
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import configuration
from lldbsuite.test_event import build_exception


class Builder:
    def getArchitecture(self):
        """Returns the architecture in effect the test suite is running with."""
        return configuration.arch if configuration.arch else ""

    def getCompiler(self):
        """Returns the compiler in effect the test suite is running with."""
        compiler = configuration.compiler if configuration.compiler else "clang"
        compiler = lldbutil.which(compiler)
        return os.path.abspath(compiler)

    def getTriple(self, arch):
        """Returns the triple for the given architecture or None."""
        return None

    def getExtraMakeArgs(self):
        """
        Helper function to return extra argumentsfor the make system. This
        method is meant to be overridden by platform specific builders.
        """
        return []

    def getArchCFlags(self, architecture):
        """Returns the ARCH_CFLAGS for the make system."""
        return []

    def getMake(self, 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"]
        if not (lldb_test and configuration.test_build_dir 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(configuration.test_build_dir, test_subdir,
                                 test_name)
        src_dir = os.path.join(configuration.test_src_root, 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, "-I",
            os.path.join(lldb_test, "make"), "-f", makefile
        ]

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

        # If d is None or an empty mapping, just return an empty list.
        if not d:
            return []

        def setOrAppendVariable(k, v):
            append_vars = ["CFLAGS", "CFLAGS_EXTRAS", "LD_EXTRAS"]
            if k in append_vars and k in os.environ:
                v = os.environ[k] + " " + v
            return '%s=%s' % (k, v)

        cmdline = [setOrAppendVariable(k, v) for k, v in list(d.items())]

        return cmdline

    def getArchSpec(self, architecture):
        """
        Helper function to return the key-value string to specify the architecture
        used for the make system.
        """
        return ["ARCH=" + architecture] if architecture else []

    def getCCSpec(self, 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 configuration.compiler:
            cc = configuration.compiler
        if cc:
            return ["CC=\"%s\"" % cc]
        return []

    def getSDKRootSpec(self):
        """
        Helper function to return the key-value string to specify the SDK root
        used for the make system.
        """
        if configuration.sdkroot:
            return ["SDKROOT={}".format(configuration.sdkroot)]
        return []

    def getModuleCacheSpec(self):
        """
        Helper function to return the key-value string to specify the clang
        module cache used for the make system.
        """
        if configuration.clang_module_cache_dir:
            return ["CLANG_MODULE_CACHE_DIR={}".format(
                configuration.clang_module_cache_dir)]
        return []

    def getLibCxxArgs(self):
        if configuration.libcxx_include_dir and configuration.libcxx_library_dir:
            libcpp_args = ["LIBCPP_INCLUDE_DIR={}".format(configuration.libcxx_include_dir),
                           "LIBCPP_LIBRARY_DIR={}".format(configuration.libcxx_library_dir)]
            if configuration.libcxx_include_target_dir:
                libcpp_args.append("LIBCPP_INCLUDE_TARGET_DIR={}".format(
                    configuration.libcxx_include_target_dir))
            return libcpp_args
        return []

    def _getDebugInfoArgs(self, debug_info):
        if debug_info is None:
            return []
        if debug_info == "dwarf":
            return ["MAKE_DSYM=NO"]
        if debug_info == "dwo":
            return ["MAKE_DSYM=NO", "MAKE_DWO=YES"]
        if debug_info == "gmodules":
            return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"]
        return None

    def getBuildCommand(self, debug_info, architecture=None, compiler=None,
            dictionary=None, testdir=None, testname=None, make_targets=None):
        debug_info_args = self._getDebugInfoArgs(debug_info)
        if debug_info_args is None:
            return None
        if make_targets is None:
            make_targets = ["all"]
        command_parts = [
            self.getMake(testdir, testname), debug_info_args, make_targets,
            self.getArchCFlags(architecture), self.getArchSpec(architecture),
            self.getCCSpec(compiler), self.getExtraMakeArgs(),
            self.getSDKRootSpec(), self.getModuleCacheSpec(),
            self.getLibCxxArgs(), self.getCmdLine(dictionary)]
        command = list(itertools.chain(*command_parts))

        return command

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