"""Build and test clangs."""

from __future__ import print_function
import sys
import logging
import os
import subprocess
import datetime
import time
import argparse
import shutil
import math
import re
import xml.etree.ElementTree as ET
from contextlib import contextmanager
from six.moves import urllib

SERVER = "labmaster2.lab.llvm.org"

NINJA = "/usr/local/bin/ninja"

MODULE_CACHE_REGEX = re.compile(r'-fmodules-cache-path=([^\"]+)')

# Add dependency checker to the Python path.
# For relative reference to the dependency file.
here = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.abspath(here + "/../../dep/"))
import dep  # noqa


def readme_name(repo):
    """Given a repo, return the name of the readme file."""
    if repo == "libcxx":
        return "LICENSE.TXT"
    return "README.txt"


def next_section(name):
    """Jenkins is setup to parse @@@ xyz @@@ as a new section of the buildlog
    with title xyz.  The section ends with @@@@@@ """
    footer()
    header(name)


def header(name):
    print("@@@", name, "@@@")


def footer():
    print("Completed at: " + time.strftime("%FT%T"))
    print("@@@@@@")


def quote_sh_string(string):
    """Make things that we print shell safe for copy and paste."""
    return "\\'".join("'" + p + "'" for p in string.split("'"))


def create_dirs(paths):
    for p in paths:
        if not os.path.exists(p):
            os.makedirs(p)


def find_system_compiler_module_cache():
    cmd = [
        'xcrun', 'clang', '-fmodules', '-x', 'c', '-', '-o', '/dev/null',
        '-###'
    ]
    output = subprocess.check_output(
        cmd, stderr=subprocess.STDOUT).decode('utf-8')
    module_cache = MODULE_CACHE_REGEX.findall(output)
    if not module_cache:
        return None
    return module_cache[0]


def find_module_caches(path):
    caches = []
    for root, dirs, _ in os.walk(path):
        for d in dirs:
            if d == "module.cache":
                caches.append(os.path.join(root, d))
    return caches

def delete_module_caches(workspace):
    caches = find_module_caches(workspace)
    system_cache = find_system_compiler_module_cache()
    if system_cache:
        caches.append(system_cache)
    for cache in caches:
        if (os.path.exists(cache)):
            print('Removing module cache: {}'.format(cache))
            shutil.rmtree(cache)


class Configuration(object):
    """docstring for Configuration"""

    def __init__(self, args):
        super(Configuration, self).__init__()
        self.sccache_path = "/usr/local/bin/sccache"

        self._args = args
        self.workspace = os.environ.get('WORKSPACE', os.getcwd())
        self._src_dir = os.environ.get('SRC_DIR', 'llvm-project')
        self._llvm_src_dir = os.environ.get('LLVM_SRC_DIR', 'llvm')
        self._lldb_src_dir = os.environ.get('LLDB_SRC_DIR', 'lldb')
        self._build_dir = os.environ.get('BUILD_DIR', 'clang-build')
        self._lldb_build_dir = os.environ.get('LLDB_BUILD_DIR', 'lldb-build')
        self._lldb_standalone_build_dir = os.environ.get('LLDB_STANDALONE_BUILD_DIR', 'lldb-standalone-build')
        self._lldb_standalone_type = os.environ.get('LLDB_STANDALONE_TYPE', 'build-tree')
        self._lldb_xcode_build_dir = os.environ.get('LLDB_XCODE_BUILD_DIR', 'lldb-xcode-build')
        self._lldb_install_dir = os.environ.get('LLDB_INSTALL_DIR', 'lldb-install')
        self._lldb_test_compiler = os.environ.get('LLDB_TEST_COMPILER', '')
        self._install_dir = os.environ.get('INSTALL_DIR', 'clang-install')
        self.j_level = os.environ.get('J_LEVEL', None)
        self.max_parallel_tests = os.environ.get('MAX_PARALLEL_TESTS', None)
        self.max_parallel_links = os.environ.get('MAX_PARALLEL_LINKS', None)
        self.host_compiler_url = os.environ.get('HOST_URL',
                                                'http://labmaster2.local/artifacts/')
        self.artifact_url = os.environ.get('ARTIFACT', 'NONE')
        self.job_name = os.environ.get('JOB_NAME', 'NONE')
        self.build_id = os.environ.get('BUILD_ID', 'NONE')
        self.build_number = os.environ.get('BUILD_NUMBER', 'NONE')
        self.svn_rev = os.environ.get('LLVM_REV', 'NONE')
        self.git_sha = os.environ.get('GIT_SHA', 'NONE')
        self.git_distance = os.environ.get('GIT_DISTANCE', 'NONE')
        self.nobootstrap = True
        self.device = None
        self.node_name = os.environ.get('NODE_NAME', None)
        self.lldb_test_archs = os.environ.get('LLDB_TEST_ARCHS', 'x86_64').split()

        # Import all of the command line arguments into the config object
        self.__dict__.update(vars(args))

    def builddir(self):
        """The build output directory for this compile."""
        return os.path.join(self.workspace, self._build_dir)

    def srcdir(self):
        """The derived source directory for this build."""
        return os.path.join(self.workspace, self._src_dir)

    def llvmsrcdir(self):
        """The llvm source directory for this build."""
        return os.path.join(self.workspace, self._src_dir, self._llvm_src_dir)

    def lldbbuilddir(self):
        """The derived source directory for this lldb build."""
        return os.path.join(self.workspace, self._lldb_build_dir)

    def lldbstandalonebuilddir(self, standalone_type):
        """The derived source directory for this lldb standalone build."""
        return os.path.join(self.workspace, standalone_type, self._lldb_standalone_build_dir)

    def lldbxcodebuilddir(self):
        """The derived source directory for this lldb Xcode build."""
        return os.path.join(self.workspace, self._lldb_xcode_build_dir)

    def lldbsrcdir(self):
        """The derived source directory for this lldb build."""
        return os.path.join(self.workspace, self._src_dir, self._lldb_src_dir)

    def lldbinstalldir(self):
        """The install directory for the lldb build."""
        return os.path.join(self.workspace, self._lldb_install_dir)

    def lldbtestcompiler(self):
        """The compiler used to build LLDB tests."""
        return self._lldb_test_compiler

    def installdir(self):
        """The install directory for the compile."""
        return os.path.join(self.workspace, self._install_dir)

    def lldbstandalonetype(self):
        """The type of standalone build: against the build or install tree."""
        return self._lldb_standalone_type;

    def CC(self):
        """Location of the host compiler, if one is present in this build."""
        cc_basedir = os.path.join(self.workspace, 'host-compiler/')
        if os.path.exists(cc_basedir):
            clang_exec_path = os.path.join(cc_basedir, 'bin/clang')
            assert os.path.exists(clang_exec_path), "host-compiler present," \
                                                    " but has no clang executable."
            return clang_exec_path
        else:
            return False

    def liblto(self):
        """Location of the host compiler, if one is present"""
        cc_basedir = os.path.join(self.workspace, 'host-compiler/')
        if os.path.exists(cc_basedir):
            clang_liblto_path = os.path.join(cc_basedir, 'lib/')
            assert os.path.exists(clang_liblto_path), "host-compiler present," \
                                                      " but has no liblto."
            return clang_liblto_path
        else:
            return False

    def branch(self):
        """Figure out the source branch name.
	   Not using GIT_BRANCH env var from Jenkins as that includes the
           remote name too.
        """
        if not os.environ.get('TESTING', False):
            try:
                cmd = ['git', '-C', conf.srcdir(), 'symbolic-ref', '--short', 'HEAD']
                out = run_collect_output(cmd, stderr=subprocess.STDOUT).strip()
            except subprocess.CalledProcessError:
                cmd = ['git', '-C', conf.srcdir(), 'rev-parse', 'HEAD']
                out = run_collect_output(cmd, stderr=subprocess.STDOUT).strip()
            return out
        return 'master'

    def link_memory_usage(self):
        """Guesstimate the maximum link memory usage for this build.
           We are only building master here so we will just use that value
        """
        #  Determinited experimentally.
        usages = {'master': 3.5}
        if self.branch() == 'master':
            return usages['master']
        else:
            raise NotImplementedError(
                "Unknown link memory usage." + self.branch())


# Global storage for configuration object.
conf = None  # type: Configuration

def cmake_builder(target):
    if not os.getenv("TESTING"):
        dep.parse_dependencies([here + "/clang_build_dependencies.dep"])

    env = []
    dyld_path = ""
    if conf.lto and conf.liblto():
        dyld_path = conf.liblto()
        env.extend(["env", "DYLD_LIBRARY_PATH=" + dyld_path])

    cmake_cmd = env + ["/usr/local/bin/cmake", "-G", "Ninja",
                       '-DCMAKE_MAKE_PROGRAM=' + NINJA,
                       "-DCMAKE_INSTALL_PREFIX=" + conf.installdir(),
                       "-DLLVM_ENABLE_PROJECTS=" + conf.llvm_enable_projects,
                       conf.llvmsrcdir()]

    compiler_flags = conf.compiler_flags
    max_parallel_links = conf.max_parallel_links

    if conf.lto:
        if conf.thinlto:
            cmake_cmd += ["-DLLVM_PARALLEL_LINK_JOBS=1"]
        else:
            cmake_cmd += ["-DLLVM_PARALLEL_LINK_JOBS=" + str(max_link_jobs())]
        cmake_cmd += ['-DLLVM_BUILD_EXAMPLES=Off']
        if not max_parallel_links:
            max_parallel_links = 1
        if dyld_path:
            cmake_cmd += ['-DDYLD_LIBRARY_PATH=' + dyld_path]
    else:
        cmake_cmd += ['-DLLVM_ENABLE_LTO=Off']
        cmake_cmd += ['-DLLVM_BUILD_EXAMPLES=On']

    cmake_cmd += ["-DCMAKE_MACOSX_RPATH=On"]

    libtool_path = query_sys_tool("macosx", "libtool")
    if libtool_path:
        cmake_cmd += ['-DCMAKE_LIBTOOL=' + libtool_path]

    if compiler_flags:
        cmake_cmd += ["-DCMAKE_C_FLAGS={}".format(' '.join(compiler_flags)),
                      "-DCMAKE_CXX_FLAGS={}".format(' '.join(compiler_flags))]

    if max_parallel_links is not None:
        cmake_cmd += ["-DLLVM_PARALLEL_LINK_JOBS={}".format(max_parallel_links)]

    if conf.CC():
        cmake_cmd += ['-DCMAKE_C_COMPILER=' + conf.CC(),
                      '-DCMAKE_CXX_COMPILER=' + conf.CC() + "++"]

    if conf.cmake_build_type:
        cmake_cmd += ["-DCMAKE_BUILD_TYPE=" + conf.cmake_build_type]
    elif conf.debug:
        cmake_cmd += ["-DCMAKE_BUILD_TYPE=Debug"]
    else:
        cmake_cmd += ["-DCMAKE_BUILD_TYPE=Release"]

    cmake_cmd += ["-DLLVM_BUILD_EXTERNAL_COMPILER_RT=On"]

    for flag in conf.cmake_flags:
        cmake_cmd += [flag]

    if conf.assertions:
        cmake_cmd += ["-DLLVM_ENABLE_ASSERTIONS=On"]
    else:
        cmake_cmd += ["-DLLVM_ENABLE_ASSERTIONS=Off"]

    if conf.globalisel:
        cmake_cmd += ["-DLLVM_BUILD_GLOBAL_ISEL=ON"]

    if conf.sccache:
        run_ws([conf.sccache_path, "--stop-server"], env={"SCCACHE_IDLE_TIMEOUT": "0"}, err_okay=True)
        run_ws([conf.sccache_path, "--start-server"], env={"SCCACHE_IDLE_TIMEOUT": "0"})
        cmake_cmd += ['-DCMAKE_C_COMPILER_LAUNCHER=' + conf.sccache_path]
        cmake_cmd += ['-DCMAKE_CXX_COMPILER_LAUNCHER=' + conf.sccache_path]

    timeout_flag = '--timeout=' + str(conf.timeout)
    lit_flags = ['--xunit-xml-output=testresults.xunit.xml', '-v', '-vv', timeout_flag]
    if conf.max_parallel_tests:
        lit_flags += ['-j', conf.max_parallel_tests]
    cmake_cmd += ['-DLLVM_LIT_ARGS={}'.format(' '.join(lit_flags))]

    ninja_cmd = env + ["/usr/local/bin/ninja", '-v']
    if conf.j_level is not None:
        ninja_cmd += ["-j", conf.j_level]

    if target == 'all' or target == 'configure' or target == 'build':
        header("Cmake")
        run_cmd(conf.builddir(), cmake_cmd)
        footer()

    if target == 'all' or target == 'build':
        header("Ninja build")

        # Build all if nothing is passed by the user.
        passed_target = conf.cmake_build_targets
        build_target = passed_target if passed_target else ['all']
        run_cmd(conf.builddir(), ninja_cmd + build_target)
        footer()
        if conf.noinstall:
            header("Skip install")
        else:
            header("Ninja install")
            run_cmd(conf.builddir(), ninja_cmd + ['install'])
            build_upload_artifact()
        footer()
    # Run all the test targets.
    ninja_cmd.extend(['-k', '0'])
    if target == 'all' or target == 'test' or target == 'testlong':
        header("Ninja test")

        targets = [
            'check-all'] if target == 'testlong' or target == 'all' else conf.cmake_test_targets

        if not targets:
            # testlong and all do check all, otherwise check and check-clang
            # unless the user asked for something else.
            targets = ['check', 'check-clang']

        run_cmd(conf.builddir(), ninja_cmd + targets)
        footer()

    if conf.sccache:
        run_ws([conf.sccache_path, "--stop-server"])


def clang_builder(target):
    """Build to set of commands to compile and test apple-clang"""

    # get rid of old archives from prior builds
    run_ws(['sh', '-c', 'rm -rfv *gz'])

    if target == "all" or target == "build":
        # Clean the build directory.
        run_ws(['rm', '-rf', 'clang.roots'])

        sdk_name = 'macosx'

        sdkroot = query_sdk_path(sdk_name)
        libtool_path = query_sys_tool(sdk_name, "libtool")

        clang_br = os.path.join(conf.workspace, conf._build_dir)
        next_section("Build Directory")
        run_ws(["mkdir", "-p", clang_br])

        toolchain = '/Applications/Xcode.app/Contents/Developer' \
                    '/Toolchains/XcodeDefault.xctoolchain'

        env = []
        dyld_path = ""
        if conf.lto and conf.liblto():
            dyld_path = conf.liblto()
            env.extend(["env", "DYLD_LIBRARY_PATH=" + dyld_path])

        next_section("Build Clang")

        if conf.sccache:
            run_ws([conf.sccache_path, "--stop-server"], env={"SCCACHE_IDLE_TIMEOUT": "0"}, err_okay=True)
            run_ws([conf.sccache_path, "--start-server"], env={"SCCACHE_IDLE_TIMEOUT": "0"})

        if conf.nobootstrap:
            if conf.debug or conf.device:
                assert False, "Invalid parameter for clang-builder."
            run_cmd(clang_br, ['mkdir',
                               './Build',
                               './Root'])
            install_prefix = conf.installdir()

            # Infer which CMake cache file to use. If ThinLTO we select a specific one.
            cmake_cachefile_thinlto = ''
            if conf.thinlto:
                cmake_cachefile_thinlto = '-ThinLTO'
            cmake_cachefile = '{}/clang/cmake/caches/Apple-stage2{}.cmake'.format(
                                       conf.srcdir(), cmake_cachefile_thinlto)

            cmake_command = env + ["/usr/local/bin/cmake", '-G', 'Ninja', '-C',
                                   cmake_cachefile,
                                   '-DLLVM_ENABLE_ASSERTIONS:BOOL={}'.format(
                                       "TRUE" if conf.assertions else "FALSE"),
                                   '-DCMAKE_BUILD_TYPE=RelWithDebInfo',
                                   '-DLLVM_ENABLE_PROJECTS={}'.format(conf.llvm_enable_projects),
                                   '-DCMAKE_MAKE_PROGRAM=' + NINJA,
                                   '-DLLVM_VERSION_PATCH=99',
                                   '-DLLVM_VERSION_SUFFIX=""',
                                   '-DLLVM_BUILD_EXTERNAL_COMPILER_RT=On',
                                   '-DCLANG_COMPILER_RT_CMAKE_ARGS={}/compiler-rt/cmake/caches/Apple.cmake'.format(
                                       conf.srcdir()),
                                   '-DCOMPILER_RT_BUILD_SANITIZERS=On',
                                   '-DCMAKE_INSTALL_PREFIX={}'.format(
                                       install_prefix),
                                   '-DCLANG_REPOSITORY_STRING={}'.format(
                                       conf.branch()),
                                   '-DCLANG_APPEND_VC_REV=On',
                                   '-DLLVM_BUILD_TESTS=On',
                                   '-DLLVM_INCLUDE_TESTS=On',
                                   '-DCLANG_INCLUDE_TESTS=On',
                                   '-DLLVM_INCLUDE_UTILS=On',
                                   '-DLIBCXX_INSTALL_HEADERS=On',
                                   '-DLIBCXX_OVERRIDE_DARWIN_INSTALL=On',
                                   '-DLIBCXX_INSTALL_LIBRARY=Off',
                                   '-DCMAKE_MACOSX_RPATH=On',
                                   ]

            if conf.sccache:
                cmake_command.append('-DCMAKE_C_COMPILER_LAUNCHER=' + conf.sccache_path)
                cmake_command.append('-DCMAKE_CXX_COMPILER_LAUNCHER=' + conf.sccache_path)

            if dyld_path:
                cmake_command += ['-DDYLD_LIBRARY_PATH=' + dyld_path]

            if libtool_path:
                cmake_command += ['-DCMAKE_LIBTOOL=' + libtool_path]

            if conf.CC():
                cmake_command.extend(['-DCMAKE_C_COMPILER=' + conf.CC(),
                                      '-DCMAKE_CXX_COMPILER=' + conf.CC() + "++"])

            timeout_flag = '--timeout=' + str(conf.timeout)
            lit_flags = ['--xunit-xml-output=testresults.xunit.xml', '-v', '-vv', timeout_flag]

            if conf.max_parallel_tests:
                lit_flags += ['-j', conf.max_parallel_tests]
            cmake_command.extend(
                ['-DLLVM_LIT_ARGS={}'.format(' '.join(lit_flags))])

            if conf.thinlto:
                cmake_command.extend(["-DLLVM_PARALLEL_LINK_JOBS=1"])
            elif conf.lto:
                cmake_command.extend(
                    ["-DLLVM_PARALLEL_LINK_JOBS=" + str(max_link_jobs())])
            else:
                cmake_command.extend(['-DLLVM_ENABLE_LTO=Off'])
                cmake_command.extend([
                    '-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -gline-tables-only -DNDEBUG',
                    '-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -gline-tables-only -DNDEBUG'])

            for flag in conf.cmake_flags:
                cmake_command += [flag]

            cmake_command.append(conf.llvmsrcdir())
            run_cmd(os.path.join(clang_br, 'Build'), cmake_command)
            next_section("Ninja")
            run_cmd(os.path.join(clang_br, 'Build'), [NINJA, '-v', 'install'])

            build_upload_artifact()

        else:
            # Two stage build, via the make files.
            print('Stage two compile TBD in near future')

    if not conf.device and (target == "test" or target == "all"):
        # Add steps to run the tests.
        next_section("Tests")
        # Auto detect bootstrap and non-bootstrap.
        obj_dir = os.path.join(conf._build_dir,
                               'Objects/obj-llvm/tools/clang/stage2-bins/')
        if not os.path.exists(obj_dir):
            obj_dir = os.path.join(conf._build_dir, 'Build/')
            obj_dir = os.path.join(conf.workspace, obj_dir)

        cmd = [NINJA, '-v', '-k', '0', 'check-all']

        if conf.assertions:
            cmd[-1] += ' --param use_gmalloc=1 ' \
                       '--param gmalloc_path=$(xcodebuild -find-library' \
                       ' libgmalloc.dylib)'
        run_cmd(obj_dir, cmd, env={'MALLOC_LOG_FILE': '/dev/null'})

    if conf.sccache:
        run_ws([conf.sccache_path, "--stop-server"])


def parse_settings_from_output(working_dir, cmd):
    old_dir = os.getcwd()
    try:
        os.chdir(working_dir)
        assignment_regex = re.compile(r"^\s+([^\s=]+)\s*=\s*(.+)$")
        settings = {}
        for line in subprocess.check_output(cmd).decode("utf-8").splitlines(True):
            match = assignment_regex.match(line)
            if match:
                settings[match.group(1)] = match.group(2)
        return settings
    finally:
        os.chdir(old_dir)


def lldb_cmake_builder(target, variant=None):
    """Do a CMake build of lldb."""

    if not os.getenv("TESTING"):
        dep.parse_dependencies([here + "/clang_build_dependencies.dep"])

    test_dir = os.path.join(conf.workspace, 'test')
    log_dir = os.path.join(test_dir, 'logs')
    results_file = os.path.join(test_dir, 'results.xml')
    create_dirs([conf.lldbbuilddir(), test_dir, log_dir])

    cmake_build_type = conf.cmake_build_type if conf.cmake_build_type else 'RelWithDebInfo'

    # Construct dotest.py arguments.
    dotest_args=['--arch', 'x86_64', '--build-dir',
                 conf.lldbbuilddir()+'/lldb-test-build.noindex',
                 '-s='+log_dir,
                 '-t',
                 '--env', 'TERM=vt100']
    dotest_args.extend(conf.dotest_flags)

    # Construct lit arguments.
    lit_args = ['-v', '--time-tests', '--shuffle',
		'--xunit-xml-output={}'.format(results_file), '-v']
    if conf.max_parallel_tests:
        lit_args.extend(['-j', conf.max_parallel_tests])
    if variant == 'sanitized':
        lit_args.extend(['--timeout 1200'])

    # Construct CMake invocation.
    cmake_cmd = ["/usr/local/bin/cmake", '-G', 'Ninja',
                 conf.llvmsrcdir(),
                 '-DCMAKE_BUILD_TYPE={}'.format(cmake_build_type),
                 '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',
                 '-DCMAKE_INSTALL_PREFIX={}'.format(conf.lldbinstalldir()),
                 '-DCMAKE_MAKE_PROGRAM={}'.format(NINJA),
                 '-DLLDB_TEST_USER_ARGS='+';'.join(dotest_args),
                 '-DLLDB_ENABLE_PYTHON=On',
                 '-DLLVM_ENABLE_ASSERTIONS:BOOL={}'.format("TRUE" if conf.assertions else "FALSE"),
                 '-DLLVM_ENABLE_MODULES=On',
                 '-DLLVM_ENABLE_PROJECTS={}'.format(conf.llvm_enable_projects),
                 '-DLLVM_LIT_ARGS={}'.format(' '.join(lit_args)),
                 '-DLLVM_VERSION_PATCH=99']

    if variant == 'sanitized':
        cmake_cmd.append('-DLLVM_TARGETS_TO_BUILD=X86')
        cmake_cmd.append('-DLLVM_USE_SANITIZER=Address;Undefined')
        # There is no need to compile the lldb tests with an asanified compiler
        # if we have a host compiler available.
        if conf.CC():
            cmake_cmd.extend([
                '-DLLDB_TEST_C_COMPILER=' + conf.CC(),
                '-DLLDB_TEST_CXX_COMPILER=' + conf.CC() + "++"
            ])

    if conf.compiler_flags:
        cmake_cmd.extend([
            "-DCMAKE_C_FLAGS={}".format(' '.join(conf.compiler_flags)),
            "-DCMAKE_CXX_FLAGS={}".format(' '.join(conf.compiler_flags))
        ])

    if conf.lldbtestcompiler():
        cmake_cmd.extend([
            '-DLLDB_TEST_C_COMPILER=' + conf.lldbtestcompiler(),
            '-DLLDB_TEST_CXX_COMPILER=' + conf.lldbtestcompiler() + "++"
        ])

    cmake_cmd.extend(conf.cmake_flags)

    if conf.CC():
        cmake_cmd.extend([
            '-DCMAKE_C_COMPILER=' + conf.CC(),
            '-DCMAKE_CXX_COMPILER=' + conf.CC() + "++"
        ])

    header("Clean")
    delete_module_caches(conf.workspace)
    footer()

    if target == 'all' or target == 'configure' or target == 'build':
        header("Cmake")
        run_cmd(conf.lldbbuilddir(), cmake_cmd)
        footer()

    if target == 'all' or target == 'build':
        header("Build")
        run_cmd(conf.lldbbuilddir(), [NINJA, '-v'])
        footer()

    if target == 'all' or target == 'install':
        header("Install")
        run_cmd(conf.lldbbuilddir(), [NINJA, '-v', 'install'])
        footer()

    if target == 'all' or target == 'testlong':
        header("Run Debug Info Tests")
        run_cmd(conf.lldbbuilddir(), [NINJA, '-v', 'check-debuginfo'])
        footer()

    if target == 'all' or target == 'test' or target == 'testlong':
        header("Run Tests")
        run_cmd(conf.lldbbuilddir(),
                ['/usr/bin/env', 'TERM=vt100', NINJA, '-v', 'check-lldb'])
        footer()

    for test_target in conf.cmake_test_targets:
        header("Run Custom Test: {0}".format(test_target))
        run_cmd(conf.lldbbuilddir(), [NINJA, '-k', '0', '-v', test_target])
        footer()


def lldb_cmake_standalone_builder(target):
    """Do a CMake standalone build of lldb."""

    standalone_type = conf.lldbstandalonetype()
    if standalone_type == "install-tree":
        llvm_dir = os.path.join(conf.installdir(), 'lib', 'cmake', 'llvm')
        clang_dir = os.path.join(conf.installdir(), 'lib', 'cmake', 'clang')
    elif standalone_type == "build-tree":
        llvm_dir = os.path.join(conf.builddir(), 'lib', 'cmake', 'llvm')
        clang_dir = os.path.join(conf.builddir(), 'lib', 'cmake', 'clang')
    else:
        raise RuntimeError(
            'Unknown standalone build type: {}'.format(standalone_type))

    test_dir = os.path.join(conf.workspace, 'test')
    log_dir = os.path.join(test_dir, 'logs')
    results_file = os.path.join(test_dir, 'results.xml')
    test_build_dir = os.path.join(conf.lldbstandalonebuilddir(
        standalone_type), 'lldb-test-build.noindex')
    create_dirs([conf.lldbstandalonebuilddir(standalone_type),
                 test_dir, log_dir, test_build_dir])
    cmake_build_type = conf.cmake_build_type if conf.cmake_build_type else 'RelWithDebInfo'
    dotest_args = [
        '--arch', 'x86_64', '--build-dir', test_build_dir,
        '-s={}'.format(log_dir), '-t', '--env', 'TERM=vt100'
    ]
    dotest_args.extend(conf.dotest_flags)

    cmake_cmd = ['/usr/local/bin/cmake', '-G', 'Ninja',
                 conf.lldbsrcdir(),
                 '-DLLVM_TARGETS_TO_BUILD=X86',
                 '-DCMAKE_BUILD_TYPE={}'.format(cmake_build_type),
                 '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',
                 '-DCMAKE_MAKE_PROGRAM={}'.format(NINJA),
                 '-DLLDB_TEST_USER_ARGS='+';'.join(dotest_args),
                 '-DLLVM_ENABLE_ASSERTIONS:BOOL={}'.format(
                     "TRUE" if conf.assertions else "FALSE"),
                 '-DLLVM_ENABLE_MODULES=Off',
                 '-DLLVM_DIR={}'.format(llvm_dir),
                 '-DClang_DIR={}'.format(clang_dir),
                 '-DLLVM_LIT_ARGS=--xunit-xml-output={} -v'.format(
                     results_file),
                 '-DLLVM_VERSION_PATCH=99']
    cmake_cmd.extend(conf.cmake_flags)

    if conf.CC():
        cmake_cmd.extend(['-DCMAKE_C_COMPILER=' + conf.CC(),
                          '-DCMAKE_CXX_COMPILER=' + conf.CC() + "++"])

    header("Clean")
    delete_module_caches(conf.workspace)
    footer()

    if target == 'all' or target == 'build':
        header("CMake")
        run_cmd(conf.lldbstandalonebuilddir(standalone_type), cmake_cmd)
        footer()

        header("Build")
        run_cmd(conf.lldbstandalonebuilddir(standalone_type), [NINJA, '-v'])
        footer()


def lldb_cmake_xcode_builder(target):
    """Do a CMake standalone build of lldb using the Xcode generator."""

    create_dirs([conf.lldbxcodebuilddir()])

    cmake_build_type = conf.cmake_build_type if conf.cmake_build_type else 'RelWithDebInfo'

    llvm_dir = os.path.join(conf.builddir(), 'lib', 'cmake', 'llvm')
    clang_dir = os.path.join(conf.builddir(), 'lib', 'cmake', 'clang')
    xcode_cache = os.path.join(conf.lldbsrcdir(), 'cmake', 'caches', 'Apple-lldb-Xcode.cmake')

    cmake_cmd = ['/usr/local/bin/cmake',
                 '-C', xcode_cache,
                 '-G', 'Xcode',
                 '-L', conf.lldbsrcdir(),
                 '-DLLVM_ENABLE_ASSERTIONS:BOOL={}'.format("TRUE" if conf.assertions else "FALSE"),
                 '-DLLVM_ENABLE_MODULES=Off',
                 '-DLLVM_DIR={}'.format(llvm_dir),
                 '-DClang_DIR={}'.format(clang_dir),
                 '-DLLVM_VERSION_PATCH=99']
    cmake_cmd.extend(conf.cmake_flags)

    build_cmd = ['/usr/local/bin/cmake',
                 '--build', '.',
                 '--config', cmake_build_type]

    test_cmd = ['/usr/bin/env', 'TERM=vt100',
                '/usr/local/bin/cmake',
                '--build', '.',
                '--config', cmake_build_type,
                '--target', 'check-lldb']

    if conf.CC():
        cmake_cmd.extend(['-DCMAKE_C_COMPILER=' + conf.CC(),
                          '-DCMAKE_CXX_COMPILER=' + conf.CC() + "++"])

    header("Clean")
    delete_module_caches(conf.workspace)
    footer()

    if target == 'all' or target == 'build':
        header("CMake")
        run_cmd(conf.lldbxcodebuilddir(), cmake_cmd)
        footer()

        header("Build")
        run_cmd(conf.lldbxcodebuilddir(), build_cmd)
        footer()

    if target == 'all' or target == 'test' or target == 'testlong':
        header("Run Tests")
        run_cmd(conf.lldbxcodebuilddir(), test_cmd)
        footer()


def static_analyzer_benchmarks_builder():
    """Run static analyzer benchmarks"""
    header("Static Analyzer Benchmarks")

    benchmark_script = conf.workspace + "/utils-analyzer/SATestBuild.py"
    benchmarks_dir = conf.workspace + "/test-suite-ClangAnalyzer/"

    compiler_bin_dir = conf.workspace + "/host-compiler/bin/"
    scanbuild_bin_dir = conf.workspace + "/tools-scan-build/bin/"

    old_path = os.environ.get("PATH", "")
    env = dict(os.environ, PATH=compiler_bin_dir + os.pathsep +
                                scanbuild_bin_dir + os.pathsep +
                                old_path)

    benchmark_cmd = [benchmark_script,
                     "--strictness", "0"
                     ]
    run_cmd(benchmarks_dir, benchmark_cmd, env=env)

    footer()


def http_download(url, dest):
    """Safely download url to dest.

    Print error and exit if download fails.
    """
    try:
        print("GETting", url, "to", dest, "...")
        f = urllib.request.urlopen(url)
        # Open our local file for writing
        with open(dest, "wb") as local_file:
            local_file.write(f.read())

    except urllib.HTTPError as e:
        print("HTTP Error:", e.code, url)
        sys.exit(1)

    except urllib.URLError as e:
        print("URL Error:", e.reason, url)
        sys.exit(1)
    print("done.")


def create_builddirs():
    create_dirs([conf.builddir(), conf.installdir()]);


def fetch_compiler():
    local_name = "host-compiler.tar.gz"
    url = conf.host_compiler_url + "/" + conf.artifact_url
    header("Fetching Compiler")
    http_download(url, conf.workspace + "/" + local_name)
    print("Decompressing...")
    if os.path.exists(conf.workspace + "/host-compiler"):
        shutil.rmtree(conf.workspace + "/host-compiler")
    os.mkdir(conf.workspace + "/host-compiler")
    run_cmd(conf.workspace + "/host-compiler/",
            ['tar', 'zxf', "../" + local_name])
    os.unlink(local_name)
    footer()

def build_upload_artifact():
    """Create artifact for this build, and upload to server."""
    if conf.noupload:
        print('Not uploading artificats')
        return
    header("Uploading Artifact")
    prop_file = "last_good_build.properties"

    artifact_name = "clang-d{}-g{}-t{}-b{}.tar.gz".format(conf.git_distance,
                                                          conf.git_sha,
                                                          conf.build_id,
                                                          conf.build_number)
    new_url = conf.job_name + "/" + artifact_name

    with open(prop_file, 'w') as prop_fd:
        prop_fd.write("LLVM_REV={}\n".format(conf.svn_rev))
        prop_fd.write("GIT_DISTANCE={}\n".format(conf.git_distance))
        prop_fd.write("GIT_SHA={}\n".format(conf.git_sha))
        prop_fd.write("ARTIFACT={}\n".format(new_url))

    # The .a's are big and we don't need them later. Drop the LLVM and clang
    # libraries, but keep the libraries from compiler-rt.
    tar = ["tar", "zcvf", "../" + artifact_name, "--exclude=*libLLVM*.a",
           "--exclude=*libclang[A-Z]*.a", "."]

    run_cmd(conf.installdir(), tar)

    mkdir_cmd = ["ssh", "buildslave@" + SERVER, "mkdir", "-p", "/Library/WebServer/Documents/artifacts/" + conf.job_name]

    run_cmd(conf.workspace, mkdir_cmd)

    upload_cmd = ["scp", artifact_name,
                  "buildslave@" + SERVER + ":/Library/WebServer/Documents/artifacts/" +
                  conf.job_name + "/"]

    run_cmd(conf.workspace, upload_cmd)

    upload_cmd = ["scp", prop_file,
                  "buildslave@" + SERVER + ":/Library/WebServer/Documents/artifacts/" +
                  conf.job_name + "/"]

    run_cmd(conf.workspace, upload_cmd)

    ln_cmd = ["ssh", "buildslave@" + SERVER,
              "ln", "-fs", "/Library/WebServer/Documents/artifacts/" +
              conf.job_name + "/" + artifact_name,
              "/Library/WebServer/Documents/artifacts/" +
              conf.job_name + "/latest"]

    run_cmd(conf.workspace, ln_cmd)

    lng_cmd = ["ssh", "buildslave@" + SERVER,
               "ln", "-fs", "/Library/WebServer/Documents/artifacts/" +
               conf.job_name + "/" + artifact_name,
               "/Library/WebServer/Documents/artifacts/" +
               conf.job_name + "/g" + conf.git_sha]
    run_cmd(conf.workspace, lng_cmd)


def run_cmd(working_dir, cmd, env=None, sudo=False, err_okay=False):
    """Run a command in a working directory, and make sure it returns zero."""
    assert type(cmd) == list, "Not a list: {}".format(type(cmd))
    old_cwd = os.getcwd()
    if env:
        envs = []
        for key, value in env.items():
            envs.append("{}={}".format(key, value))
        cmd = ["env"] + envs + cmd
    if sudo:
        cmd = ['sudo'] + cmd

    cmd_to_print = ' '.join([quote_sh_string(x) for x in cmd])
    sys.stdout.write("cd {}\n{}\n".format(working_dir, cmd_to_print))
    sys.stdout.flush()
    return_code = 0
    start_time = datetime.datetime.now()
    ignore_errors_override = os.environ.get('IGNORE_ERRORS_OVERRIDE', False)
    if not os.environ.get('TESTING', False):
        try:
            os.chdir(working_dir)
            subprocess.check_call(cmd)
            os.chdir(old_cwd)
        except subprocess.CalledProcessError as excpt:
            if not err_okay and not ignore_errors_override:
                raise excpt
            else:
                logging.info("Ignoring failed command.")
                return_code = excpt.returncode
    end_time = datetime.datetime.now()

    logging.info("Command took {} seconds".format(
        (end_time - start_time).seconds))
    return return_code


KNOWN_TARGETS = ['all', 'configure', 'build', 'test', 'testlong', 'install']
KNOWN_BUILDS = [
    'clang', 'cmake', 'lldb-cmake', 'lldb-cmake-standalone',
    'lldb-cmake-xcode', 'lldb-cmake-sanitized', 'lldb-cmake-matrix', 'fetch',
    'artifact', 'static-analyzer-benchmarks'
]


def query_sdk_path(sdk_name):
    """Get the path to the sdk named using xcrun.

    When $TESTING define, just give a dummy back.  We do this because xcrun
    could fail if the sdk you want is not installed, and that is silly for
    testing.
    """

    if not os.environ.get('TESTING', False):
        cmd = ['xcrun', '--sdk', sdk_name, '--show-sdk-path']
        return run_collect_output(cmd).strip()
    else:
        return "/Applications/Xcode.app/Contents/Developer/Platforms/" \
               "MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk"


def max_link_jobs():
    """Link jobs take about 3.6GB of memory, max."""
    mem_str = run_collect_output(["sysctl", "hw.memsize"])
    mem = float(mem_str.split()[1].strip())
    mem = mem / (1024.0 ** 3)  # Conver to GBs.
    return int(math.ceil(mem / conf.link_memory_usage()))


TEST_VALS = {"sysctl hw.ncpu": "hw.ncpu: 8\n",
             "sysctl hw.memsize": "hw.memsize: 8589934592\n",
             "xcrun --sdk iphoneos --show-sdk-path": "/Foo/bar",
             "/usr/bin/xcrun svn upgrade": "",
             }


@contextmanager
def cwd(path):
    last_cwd = os.getcwd()
    if path:
        os.chdir(path)
    try:
        yield
    finally:
        os.chdir(last_cwd)


def run_collect_output(cmd, working_dir=None, stderr=None):
    """Run cmd and then return the output.

    If working_dir is supplied the cmd will run in
    with a context manager in working_dir.
    """
    if os.getenv("TESTING"):
        print('TV: ' + ' '.join(cmd))
        return TEST_VALS[' '.join(cmd)]

    with cwd(working_dir):
        return subprocess.check_output(cmd, stderr=stderr).decode("utf-8")


def query_sys_tool(sdk_name, tool_name):
    """Get the path of system tool

    When $TESTING define, just give a dummy back.
    """

    if not os.environ.get('TESTING', False):
        cmd = ['xcrun', '--sdk', sdk_name, '--find', tool_name]
        return run_collect_output(cmd).strip()
    else:
        return "/usr/bin/" + tool_name


def run_ws(cmd, env=None, sudo=False, err_okay=False):
    """Wrapper to call run_cmd in local workspace.

    Since 99 percent of the time, that is where you want to call things from.
    """
    return run_cmd(conf.workspace, cmd, env, sudo=sudo, err_okay=err_okay)


def parse_args():
    """Get the command line arguments, and make sure they are correct."""

    parser = argparse.ArgumentParser(
        description='Build and test compilers and other things.')

    parser.add_argument("build_type",
                        help="The kind of build to trigger.",
                        choices=KNOWN_BUILDS)

    parser.add_argument("build_target",
                        nargs='?',
                        help="The targets to call (build, check, etc).",
                        choices=KNOWN_TARGETS)

    parser.add_argument('--assertions', dest='assertions', action='store_true')
    parser.add_argument('--lto', dest='lto', action='store_true')
    parser.add_argument('--thinlto', dest='thinlto', action='store_true')
    parser.add_argument('--debug', dest='debug', action='store_true')
    parser.add_argument('--cmake-type', dest='cmake_build_type',
                        help="Override cmake type Release, Debug, "
                             "RelWithDebInfo and MinSizeRel")
    parser.add_argument('--cmake-flag', dest='cmake_flags',
                        action='append', default=[],
                        help='Set an arbitrary cmake flag')
    parser.add_argument('--dotest-flag', dest='dotest_flags',
                        action='append', default=[],
                        help='Set an arbitrary lldb dotest.py flag')
    parser.add_argument('--cmake-test-target', dest='cmake_test_targets',
                        action='append', default=[],
                        help='Targets to build during testing')
    parser.add_argument('--cmake-build-target', dest='cmake_build_targets',
                        action='append', default=[],
                        help='Targets to build during building.')
    parser.add_argument('--compiler-flag', dest='compiler_flags',
                        action='append', default=[],
                        help='Set an arbitrary compiler flag')
    parser.add_argument('--noupload', dest='noupload', action='store_true')
    parser.add_argument('--noinstall', dest='noinstall', action='store_true',
                        help="Disable the install stage, build only.")
    parser.add_argument('--sccache', dest='sccache',
                        action='store_true', default=False,
                        help="If the builds supports it, use sccache.")
    parser.add_argument('--globalisel', dest='globalisel',
                        action='store_true', help="Turn on the experimental"
                                                  " GlobalISel CMake flag.")
    parser.add_argument('--projects', dest='llvm_enable_projects',
                        default="clang;clang-tools-extra;compiler-rt;libcxx",
                        help="Semicolon seperated list of projects to build.")
    parser.add_argument('--timeout', dest='timeout', type=int, default='600',
                        help='Individual test timeout in seconds.')
    args = parser.parse_args()
    if args.thinlto:
        args.lto = True
    return args


def main():
    """Run a build based on command line args and ENV."""
    global conf
    args = parse_args()
    conf = Configuration(args)

    create_builddirs()
    try:
        if args.build_type == 'clang':
            clang_builder(args.build_target)
        elif args.build_type == 'lldb-cmake':
            lldb_cmake_builder(args.build_target)
        elif args.build_type == 'lldb-cmake-sanitized':
            lldb_cmake_builder(args.build_target, 'sanitized')
        elif args.build_type == 'lldb-cmake-matrix':
            lldb_cmake_builder(args.build_target, 'matrix')
        elif args.build_type == 'lldb-cmake-standalone':
            lldb_cmake_standalone_builder(args.build_target)
        elif args.build_type == 'lldb-cmake-xcode':
            lldb_cmake_xcode_builder(args.build_target)
        elif args.build_type == 'cmake':
            cmake_builder(args.build_target)
        elif args.build_type == 'fetch':
            fetch_compiler()
        elif args.build_type == 'artifact':
            build_upload_artifact()
        elif args.build_type == 'static-analyzer-benchmarks':
            static_analyzer_benchmarks_builder()
    except subprocess.CalledProcessError as exct:
        print('Command failed: {}'.format(exct))
        print('Command:', exct.cmd)
        sys.exit(1)


if __name__ == '__main__':
    main()
