#!/usr/bin/env python

import errno
import hashlib
import fnmatch
import os
import platform
import re
import repo
import subprocess
import sys

from lldbbuild import *

#### SETTINGS ####

def LLVM_HASH_INCLUDES_DIFFS():
    return False

# For use with Xcode-style builds

def process_vcs(vcs):
    return {
        "svn": VCS.svn,
        "git": VCS.git
    }[vcs]

def process_root(name):
    return {
        "llvm": llvm_source_path(),
        "clang": clang_source_path(),
        "ninja": ninja_source_path()
    }[name]

def process_repo(r):
    return {
        'name': r["name"],
        'vcs': process_vcs(r["vcs"]),
        'root': process_root(r["name"]),
        'url': r["url"],
        'ref': r["ref"]
    }

def fallback_repo(name):
    return {
        'name': name,
        'vcs': None,
        'root': process_root(name),
        'url': None,
        'ref': None
    }

def dirs_exist(names):
    for name in names:
        if not os.path.isdir(process_root(name)):
            return False
    return True

def XCODE_REPOSITORIES():
    names = ["llvm", "clang", "ninja"]
    if dirs_exist(names):
        return [fallback_repo(n) for n in names]
    override = repo.get_override()
    if override:
        return [process_repo(r) for r in override]
    identifier = repo.identifier()
    if identifier == None:
        identifier = "<invalid>" # repo.find will just use the fallback file
    set = repo.find(identifier)
    return [process_repo(r) for r in set]


def get_c_compiler():
    return subprocess.check_output([
        'xcrun',
        '--sdk', 'macosx',
        '-find', 'clang'
    ]).rstrip()


def get_cxx_compiler():
    return subprocess.check_output([
        'xcrun',
        '--sdk', 'macosx',
        '-find', 'clang++'
    ]).rstrip()

#                 CFLAGS="-isysroot $(xcrun --sdk macosx --show-sdk-path) -mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \
#                        LDFLAGS="-mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \


def get_deployment_target():
    return os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)


def get_c_flags():
    cflags = ''
    # sdk_path = subprocess.check_output([
    #     'xcrun',
    #     '--sdk', 'macosx',
    #     '--show-sdk-path']).rstrip()
    # cflags += '-isysroot {}'.format(sdk_path)

    deployment_target = get_deployment_target()
    if deployment_target:
        # cflags += ' -mmacosx-version-min={}'.format(deployment_target)
        pass

    return cflags


def get_cxx_flags():
    return get_c_flags()


def get_common_linker_flags():
    linker_flags = ""
    deployment_target = get_deployment_target()
    if deployment_target:
        # if len(linker_flags) > 0:
        #     linker_flags += ' '
        # linker_flags += '-mmacosx-version-min={}'.format(deployment_target)
        pass

    return linker_flags


def get_exe_linker_flags():
    return get_common_linker_flags()


def get_shared_linker_flags():
    return get_common_linker_flags()


def CMAKE_FLAGS():
    return {
        "Debug": [
            "-DCMAKE_BUILD_TYPE=RelWithDebInfo",
            "-DLLVM_ENABLE_ASSERTIONS=ON",
        ],
        "DebugClang": [
            "-DCMAKE_BUILD_TYPE=Debug",
            "-DLLVM_ENABLE_ASSERTIONS=ON",
        ],
        "Release": [
            "-DCMAKE_BUILD_TYPE=Release",
            "-DLLVM_ENABLE_ASSERTIONS=ON",
        ],
        "BuildAndIntegration": [
            "-DCMAKE_BUILD_TYPE=Release",
            "-DLLVM_ENABLE_ASSERTIONS=OFF",
        ],
    }


def CMAKE_ENVIRONMENT():
    return {
    }

#### COLLECTING ALL ARCHIVES ####


def collect_archives_in_path(path):
    files = os.listdir(path)
    # Only use libclang and libLLVM archives, and exclude libclang_rt
    regexp = "^lib(clang[^_]|LLVM|gtest).*$"
    return [
        os.path.join(
            path,
            file) for file in files if file.endswith(".a") and re.match(
            regexp,
            file)]


def archive_list():
    paths = library_paths()
    archive_lists = [collect_archives_in_path(path) for path in paths]
    return [archive for archive_list in archive_lists for archive in archive_list]


def write_archives_txt():
    f = open(archives_txt(), 'w')
    for archive in archive_list():
        f.write(archive + "\n")
    f.close()

#### COLLECTING REPOSITORY MD5S ####


def source_control_status(spec):
    vcs_for_spec = vcs(spec)
    if LLVM_HASH_INCLUDES_DIFFS():
        return vcs_for_spec.status() + vcs_for_spec.diff()
    else:
        return vcs_for_spec.status()


def source_control_status_for_specs(specs):
    statuses = [source_control_status(spec) for spec in specs]
    return "".join(statuses)


def all_source_control_status():
    return source_control_status_for_specs(XCODE_REPOSITORIES())


def md5(string):
    m = hashlib.md5()
    m.update(string)
    return m.hexdigest()


def all_source_control_status_md5():
    return md5(all_source_control_status())

#### CHECKING OUT AND BUILDING LLVM ####


def apply_patches(spec):
    files = os.listdir(os.path.join(lldb_source_path(), 'scripts'))
    patches = [
        f for f in files if fnmatch.fnmatch(
            f, spec['name'] + '.*.diff')]
    for p in patches:
        run_in_directory(["patch",
                          "-p1",
                          "-i",
                          os.path.join(lldb_source_path(),
                                       'scripts',
                                       p)],
                         spec['root'])


def check_out_if_needed(spec):
    if not os.path.isdir(spec['root']):
        vcs(spec).check_out()
        apply_patches(spec)


def all_check_out_if_needed():
    for r in XCODE_REPOSITORIES():
        check_out_if_needed(r)


def should_build_llvm():
    if build_type() == BuildType.Xcode:
        # TODO use md5 sums
        return True


def do_symlink(source_path, link_path):
    print("Symlinking " + source_path + " to " + link_path)
    if os.path.islink(link_path):
        os.remove(link_path)
    if not os.path.exists(link_path):
        os.symlink(source_path, link_path)


def setup_source_symlink(repo):
    source_path = repo["root"]
    link_path = os.path.join(lldb_source_path(), os.path.basename(source_path))
    do_symlink(source_path, link_path)


def setup_source_symlinks():
    for r in XCODE_REPOSITORIES():
        setup_source_symlink(r)


def setup_build_symlink():
    # We don't use the build symlinks in llvm.org Xcode-based builds.
    if build_type() != BuildType.Xcode:
        source_path = package_build_path()
        link_path = expected_package_build_path()
        do_symlink(source_path, link_path)


def should_run_cmake(cmake_build_dir):
    # We need to run cmake if our llvm build directory doesn't yet exist.
    if not os.path.exists(cmake_build_dir):
        return True

    # Wee also need to run cmake if for some reason we don't have a ninja
    # build file.  (Perhaps the cmake invocation failed, which this current
    # build may have fixed).
    ninja_path = os.path.join(cmake_build_dir, "build.ninja")
    return not os.path.exists(ninja_path)


def cmake_environment():
    cmake_env = join_dicts(os.environ, CMAKE_ENVIRONMENT())
    return cmake_env


def is_executable(path):
    return os.path.isfile(path) and os.access(path, os.X_OK)


def find_executable_in_paths(program, paths_to_check):
    program_dir, program_name = os.path.split(program)
    if program_dir:
        if is_executable(program):
            return program
    else:
        for path_dir in paths_to_check:
            path_dir = path_dir.strip('"')
            executable_file = os.path.join(path_dir, program)
            if is_executable(executable_file):
                return executable_file
    return None


def find_cmake():
    # First check the system PATH env var for cmake
    cmake_binary = find_executable_in_paths(
        "cmake", os.environ["PATH"].split(os.pathsep))
    if cmake_binary:
        # We found it there, use it.
        return cmake_binary

    # Check a few more common spots.  Xcode launched from Finder
    # will have the default environment, and may not have
    # all the normal places present.
    extra_cmake_dirs = [
        "/usr/local/bin",
        "/opt/local/bin",
        os.path.join(os.path.expanduser("~"), "bin")
    ]

    if platform.system() == "Darwin":
        # Add locations where an official CMake.app package may be installed.
        extra_cmake_dirs.extend([
            os.path.join(
                os.path.expanduser("~"),
                "Applications",
                "CMake.app",
                "Contents",
                "bin"),
            os.path.join(
                os.sep,
                "Applications",
                "CMake.app",
                "Contents",
                "bin")])

    cmake_binary = find_executable_in_paths("cmake", extra_cmake_dirs)
    if cmake_binary:
        # We found it in one of the usual places.  Use that.
        return cmake_binary

    # We couldn't find cmake.  Tell the user what to do.
    raise Exception(
        "could not find cmake in PATH ({}) or in any of these locations ({}), "
        "please install cmake or add a link to it in one of those locations".format(
            os.environ["PATH"], extra_cmake_dirs))


def cmake_flags():
    cmake_flags = CMAKE_FLAGS()[lldb_configuration()]
    cmake_flags += ["-GNinja",
                    "-DCMAKE_C_COMPILER={}".format(get_c_compiler()),
                    "-DCMAKE_CXX_COMPILER={}".format(get_cxx_compiler()),
                    "-DCMAKE_INSTALL_PREFIX={}".format(expected_package_build_path_for("llvm")),
                    "-DCMAKE_C_FLAGS={}".format(get_c_flags()),
                    "-DCMAKE_CXX_FLAGS={}".format(get_cxx_flags()),
                    "-DCMAKE_EXE_LINKER_FLAGS={}".format(get_exe_linker_flags()),
                    "-DCMAKE_SHARED_LINKER_FLAGS={}".format(get_shared_linker_flags()),
                    "-DHAVE_CRASHREPORTER_INFO=1"]
    deployment_target = get_deployment_target()
    if deployment_target:
        cmake_flags.append(
            "-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target))
    return cmake_flags


def run_cmake(cmake_build_dir, ninja_binary_path):
    cmake_binary = find_cmake()
    print("found cmake binary: using \"{}\"".format(cmake_binary))

    command_line = [cmake_binary] + cmake_flags() + [
        "-DCMAKE_MAKE_PROGRAM={}".format(ninja_binary_path),
        llvm_source_path()]
    print("running cmake like so: ({}) in dir ({})".format(command_line, cmake_build_dir))

    subprocess.check_call(
        command_line,
        cwd=cmake_build_dir,
        env=cmake_environment())


def create_directories_as_needed(path):
    try:
        os.makedirs(path)
    except OSError as error:
        # An error indicating that the directory exists already is fine.
        # Anything else should be passed along.
        if error.errno != errno.EEXIST:
            raise error


def run_cmake_if_needed(ninja_binary_path):
    cmake_build_dir = package_build_path()
    if should_run_cmake(cmake_build_dir):
        # Create the build directory as needed
        create_directories_as_needed(cmake_build_dir)
        run_cmake(cmake_build_dir, ninja_binary_path)


def build_ninja_if_needed():
    # First check if ninja is in our path.  If so, there's nothing to do.
    ninja_binary_path = find_executable_in_paths(
        "ninja", os.environ["PATH"].split(os.pathsep))
    if ninja_binary_path:
        # It's on the path.  cmake will find it.  We're good.
        print("found ninja here: \"{}\"".format(ninja_binary_path))
        return ninja_binary_path

    # Figure out if we need to build it.
    ninja_build_dir = ninja_source_path()
    ninja_binary_path = os.path.join(ninja_build_dir, "ninja")
    if not is_executable(ninja_binary_path):
        # Build ninja
        command_line = ["python", "configure.py", "--bootstrap"]
        print("building ninja like so: ({}) in dir ({})".format(command_line, ninja_build_dir))
        subprocess.check_call(
            command_line,
            cwd=ninja_build_dir,
            env=os.environ)

    return ninja_binary_path


def join_dicts(dict1, dict2):
    d = dict1.copy()
    d.update(dict2)
    return d


def build_llvm(ninja_binary_path):
    cmake_build_dir = package_build_path()
    subprocess.check_call(
        [ninja_binary_path],
        cwd=cmake_build_dir,
        env=cmake_environment())


def build_llvm_if_needed():
    if should_build_llvm():
        ninja_binary_path = build_ninja_if_needed()
        run_cmake_if_needed(ninja_binary_path)
        build_llvm(ninja_binary_path)
        setup_build_symlink()

#### MAIN LOGIC ####

if __name__ == "__main__":
    all_check_out_if_needed()
    build_llvm_if_needed()
    write_archives_txt()
    sys.exit(0)
