"""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._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):
            cmd = ['git', '-C', conf.srcdir(), 'symbolic-ref', '--short', 'HEAD']
            out = run_collect_output(cmd).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"]

    lit_flags = ['--xunit-xml-output=testresults.xunit.xml', '-v', '--timeout=600']
    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()


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.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 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() + "++"])

            lit_flags = ['--xunit-xml-output=testresults.xunit.xml', '-v', '--timeout=600']
            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'})


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=Off',
                 '-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')

    if variant == 'sanitized':
        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-shell']

    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):
    """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)


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('--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.")

    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()
