"""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')
    results_file = os.path.join(test_dir, 'results.xml')
    create_dirs([conf.lldbbuilddir(), test_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',
                 '-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')
    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, 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,
        '-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()
