#!/usr/bin/env python3
import argparse
import os
import re
import shlex
import subprocess
import sys
import textwrap

def get_relevant_bolt_changes(dir: str) -> str:
    # Return a list of bolt source changes that are relevant to testing.
    all_changes = subprocess.run(
        shlex.split("git show HEAD --name-only --pretty=''"),
        cwd=dir,
        text=True,
        stdout=subprocess.PIPE,
    )
    keep_bolt = subprocess.run(
        shlex.split("grep '^bolt'"),
        input=all_changes.stdout,
        text=True,
        stdout=subprocess.PIPE,
    )
    keep_relevant = subprocess.run(
        shlex.split(
            "grep -v -e '^bolt/docs' -e '^bolt/utils/docker' -e '^bolt/utils/dot2html'"
        ),
        input=keep_bolt.stdout,
        text=True,
        stdout=subprocess.PIPE,
    )
    return keep_relevant.stdout

def get_git_ref_or_rev(dir: str) -> str:
    # Run 'git symbolic-ref -q --short HEAD || git rev-parse --short HEAD'
    cmd_ref = "git symbolic-ref -q --short HEAD"
    ref = subprocess.run(
        shlex.split(cmd_ref), cwd=dir, text=True, stdout=subprocess.PIPE
    )
    if not ref.returncode:
        return ref.stdout.strip()
    cmd_rev = "git rev-parse --short HEAD"
    return subprocess.check_output(shlex.split(cmd_rev), cwd=dir, text=True).strip()


def main():
    parser = argparse.ArgumentParser(
        description=textwrap.dedent(
            """
            This script builds two versions of BOLT (with the current and
            previous revision) and sets up symlink for llvm-bolt-wrapper.
            Passes the options through to llvm-bolt-wrapper.
            """
        )
    )
    parser.add_argument(
        "build_dir",
        nargs="?",
        default=os.getcwd(),
        help="Path to BOLT build directory, default is current " "directory",
    )
    parser.add_argument(
        "--check-bolt-sources",
        default=False,
        action="store_true",
        help="Create a marker file (.llvm-bolt.changes) if any relevant BOLT sources are modified",
    )
    parser.add_argument(
        "--switch-back",
        default=False,
        action="store_true",
        help="Checkout back to the starting revision",
    )
    parser.add_argument(
        "--cmp-rev",
        default="HEAD^",
        help="Revision to checkout to compare vs HEAD",
    )
    args, wrapper_args = parser.parse_known_args()
    bolt_path = f"{args.build_dir}/bin/llvm-bolt"

    source_dir = None
    # find the repo directory
    with open(f"{args.build_dir}/CMakeCache.txt") as f:
        for line in f:
            m = re.match(r"LLVM_SOURCE_DIR:STATIC=(.*)", line)
            if m:
                source_dir = m.groups()[0]
    if not source_dir:
        sys.exit("Source directory is not found")

    script_dir = os.path.dirname(os.path.abspath(__file__))
    wrapper_path = f"{script_dir}/llvm-bolt-wrapper.py"
    # build the current commit
    subprocess.run(
        shlex.split("cmake --build . --target llvm-bolt"), cwd=args.build_dir
    )
    # rename llvm-bolt
    os.replace(bolt_path, f"{bolt_path}.new")
    # memorize the old hash for logging
    old_ref = get_git_ref_or_rev(source_dir)

    if args.check_bolt_sources:
        marker = f"{args.build_dir}/.llvm-bolt.changes"
        if os.path.exists(marker):
            os.remove(marker)
        file_changes = get_relevant_bolt_changes(source_dir)
        # Create a marker file if any relevant BOLT source files changed.
        if len(file_changes) > 0:
            print(f"BOLT source changes were found:\n{file_changes}")
            open(marker, "a").close()

    # determine whether a stash is needed
    stash = subprocess.run(
        shlex.split("git status --porcelain"),
        cwd=source_dir,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True,
    ).stdout
    if stash:
        # save local changes before checkout
        subprocess.run(shlex.split("git stash push -u"), cwd=source_dir)
    # check out the previous/cmp commit
    subprocess.run(shlex.split(f"git checkout -f {args.cmp_rev}"), cwd=source_dir)
    # get the parent commit hash for logging
    new_ref = get_git_ref_or_rev(source_dir)
    # build the previous commit
    subprocess.run(
        shlex.split("cmake --build . --target llvm-bolt"), cwd=args.build_dir
    )
    # rename llvm-bolt
    os.replace(bolt_path, f"{bolt_path}.old")
    # set up llvm-bolt-wrapper.ini
    ini = subprocess.check_output(
        shlex.split(f"{wrapper_path} {bolt_path}.old {bolt_path}.new") + wrapper_args,
        text=True,
    )
    with open(f"{args.build_dir}/bin/llvm-bolt-wrapper.ini", "w") as f:
        f.write(ini)
    # symlink llvm-bolt-wrapper
    os.symlink(wrapper_path, bolt_path)
    if args.switch_back:
        if stash:
            subprocess.run(shlex.split("git stash pop"), cwd=source_dir)
        subprocess.run(shlex.split(f"git checkout {old_ref}"), cwd=source_dir)
    else:
        print(
            f"The repository {source_dir} has been switched from {old_ref} "
            f"to {new_ref}. Local changes were stashed. Switch back using\n\t"
            f"git checkout {old_ref}\n"
        )
    print(
        f"Build directory {args.build_dir} is ready to run BOLT tests, e.g.\n"
        "\tbin/llvm-lit -sv tools/bolt/test\nor\n"
        "\tbin/llvm-lit -sv tools/bolttests"
    )


if __name__ == "__main__":
    main()
