#!/usr/bin/env python3

import argparse
import os
import subprocess
import sys
import tempfile

# Unofficial list of directories required to build libc++. This is a best guess that should work
# when checking out the monorepo at most commits, but it's technically not guaranteed to work
# (especially for much older commits).
LIBCXX_REQUIRED_DIRECTORIES = [
    'libcxx',
    'libcxxabi',
    'llvm/cmake',
    'llvm/utils/llvm-lit',
    'llvm/utils/lit',
    'runtimes',
    'cmake',
    'third-party/benchmark',
    'libc'
]

def directory_path(string):
    if os.path.isdir(string):
        return string
    else:
        raise NotADirectoryError(string)

def resolve_commit(git_repo, commit):
    """
    Resolve the full commit SHA from any tree-ish.
    """
    return subprocess.check_output(['git', '-C', git_repo, 'rev-parse', commit], text=True).strip()

def checkout_subdirectories(git_repo, commit, paths, destination):
    """
    Produce a copy of the specified Git-tracked files/directories at the given commit.
    The resulting files and directories at placed at the given location.
    """
    with tempfile.TemporaryDirectory() as tmp:
        tmpfile = os.path.join(tmp, 'archive.tar.gz')
        git_archive = ['git', '-C', git_repo, 'archive', '--format', 'tar.gz', '--output', tmpfile, commit, '--'] + list(paths)
        subprocess.check_call(git_archive)
        os.makedirs(destination, exist_ok=True)
        subprocess.check_call(['tar', '-x', '-z', '-f', tmpfile, '-C', destination])

def build_libcxx(src_dir, build_dir, install_dir, cmake_options):
    """
    Build and install libc++ using the provided source, build and installation directories.
    """
    configure = ['cmake', '-S', os.path.join(src_dir, 'runtimes'), '-B', build_dir, '-G', 'Ninja']
    configure += ['-D', 'LLVM_ENABLE_RUNTIMES=libcxx;libcxxabi']
    configure += ['-D', f'CMAKE_INSTALL_PREFIX={install_dir}']
    configure += ['-D', 'LIBCXXABI_USE_LLVM_UNWINDER=OFF']
    configure += list(cmake_options)
    subprocess.check_call(configure)

    build = ['cmake', '--build', build_dir, '--target', 'install']
    subprocess.check_call(build)

def exists_in_commit(git_repo, commit, path):
    """
    Return whether the given path (file or directory) existed at the given commit.
    """
    cmd = ['git', '-C', git_repo, 'show', f'{commit}:{path}']
    result = subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    return result == 0

def main(argv):
    parser = argparse.ArgumentParser(
        prog='build-at-commit',
        description='Attempt to build libc++ at the specified commit. '
                    'This script checks out libc++ at the given commit and does a best effort attempt '
                    'to build it and install it to the specified location. This can be useful when '
                    'performing bisections or historical analyses of libc++ behavior, performance, etc. '
                    'This may not work for some commits, for example commits where the library is broken '
                    'or much older commits when the build process was different from today\'s build process.')
    parser.add_argument('--commit', type=str, required=True,
        help='Commit to checkout and build.')
    parser.add_argument('--install-dir', type=str, required=True,
        help='Path to install the library at. This is equivalent to the `CMAKE_INSTALL_PREFIX` '
             'used when building.')
    parser.add_argument('cmake_options', nargs=argparse.REMAINDER,
        help='Optional arguments passed to CMake when configuring the build. Should be provided last and '
             'separated from other arguments with a `--`.')
    parser.add_argument('--git-repo', type=directory_path, default=os.getcwd(),
        help='Optional path to the Git repository to use. By default, the current working directory is used.')
    parser.add_argument('--tmp-src-dir', type=str, required=False,
        help='Optional path to use for the ephemeral source checkout used to perform the build. '
             'By default, a temporary directory is used and it is cleaned up after the build. '
             'If a custom directory is specified, it is not cleaned up automatically.')
    parser.add_argument('--tmp-build-dir', type=str, required=False,
        help='Optional path to use for the ephemeral build directory used during the build.'
             'By default, a temporary directory is used and it is cleaned up after the build. '
             'If a custom directory is specified, it is not cleaned up automatically.')
    args = parser.parse_args(argv)

    # Gather CMake options
    cmake_options = []
    if args.cmake_options is not None:
        if args.cmake_options[0] != '--':
            raise ArgumentError('For clarity, CMake options must be separated from other options by --')
        cmake_options = args.cmake_options[1:]

    # Figure out which directories to check out at the given commit. We avoid checking
    # out the whole monorepo as an optimization.
    sha = resolve_commit(args.git_repo, args.commit)
    checkout_dirs = [d for d in LIBCXX_REQUIRED_DIRECTORIES if exists_in_commit(args.git_repo, sha, d)]

    tempdirs = []
    if args.tmp_src_dir is not None:
        src_dir = args.tmp_src_dir
    else:
        tempdirs.append(tempfile.TemporaryDirectory())
        src_dir = tempdirs[-1].name

    if args.tmp_build_dir is not None:
        build_dir = args.tmp_build_dir
    else:
        tempdirs.append(tempfile.TemporaryDirectory())
        build_dir = tempdirs[-1].name

    try:
        checkout_subdirectories(args.git_repo, sha, checkout_dirs, src_dir)
        build_libcxx(src_dir, build_dir, args.install_dir, cmake_options)
    finally:
        for d in tempdirs:
            d.cleanup()

if __name__ == '__main__':
    main(sys.argv[1:])
