#!/usr/bin/env python3
#
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
from collections.abc import Iterator
from contextlib import contextmanager
from pathlib import Path
import shutil
import subprocess
import sys
from tempfile import TemporaryDirectory
from typing import Optional, TextIO

import context

from android_rust import build_platform
from android_rust.paths import *
from android_rust.toolchains import CLANG_TOOLCHAIN_HOST, ClangToolchain, RustToolchain
from android_rust.utils import (
    TERM_RED,
    ExtantPath,
    ResolvedPath,
    ScriptException,
    archive_create,
    archive_extract,
    extend_suffix,
    get_prebuilt_binary_paths,
    print_colored,
    print_fs_tree,
    is_archive,
    reify_singleton_patterns)

from test_compiler import initialize_clang_prebuilt

#
# Constants
#

BOLT_INSTRUMENTATION_SUBJECTS: list[str] = [
    "lib/librustc_driver-*.so",
    "lib/libstd-*.so",
    "lib/libLLVM.so.*",
]

BOLT_SKIP_FUNCS: dict[str, list[str]] = {
    "librustc_driver": ["blake3_hash_many_sse2/1",],
}

#
# Program logic
#


def parse_args() -> argparse.Namespace:
    """Parses arguments and returns the parsed structure."""
    parser = argparse.ArgumentParser("Run BOLT on a Rust toolchain archive")
    parser.add_argument(
        "archive_path", type=ExtantPath, help="Path to the prebuilt archive to instrument/optimize")

    parser.add_argument(
        "--build-name",
        default="bolted",
        help="Desired filename for the output archive (w/o extension)")
    parser.add_argument(
        "--dist",
        "-d",
        dest="dist_path",
        type=ResolvedPath,
        default=DIST_PATH_DEFAULT,
        help="Where to place distributable artifacts")
    parser.add_argument(
        "--clang-prebuilt",
        type=ExtantPath,
        default=CLANG_TOOLCHAIN_HOST,
        help="Path to Clang toolchain that will be used to merge profile data")

    parser.add_argument(
        "--strip-only", action="store_true", help="Don't invoke BOLT, just strip the binaries")

    action_group = parser.add_mutually_exclusive_group()
    action_group.add_argument(
        "--profile-generate",
        type=ExtantPath,
        nargs="?",
        const=OUT_PATH_PROFILES,
        help="Instrument the toolchain for BOLT profile generation with an absolute path")
    action_group.add_argument(
        "--profile-generate-relative",
        type=Path,
        nargs="?",
        const=Path("out/profiles"),
        help="Instrument the toolchain for BOLT profile generation with a relative path")
    action_group.add_argument(
        "--profile-use",
        type=ExtantPath,
        nargs="?",
        const=OUT_PATH_PROFILES,
        help="Path to archive or directory with a bolt/ subdir containing BOLT profiles")

    return parser.parse_args()


@contextmanager
def handle_input_path(input_path: Path) -> Iterator[Path]:
    if is_archive(input_path):
        with TemporaryDirectory() as temp_dir:
            temp_dir_path = Path(temp_dir)
            print(f"Unpacking archive into {temp_dir}")
            archive_extract(input_path, temp_dir_path)
            yield temp_dir_path
    else:
        yield input_path


@contextmanager
def expand_profiles(profile_path: Path | None) -> Iterator[Path | None]:
    if profile_path is not None:
        if is_archive(profile_path):
            with TemporaryDirectory() as temp_dir:
                temp_dir_path = Path(temp_dir)
                print(f"Unpacking profiles into {temp_dir}")
                archive_extract(profile_path, temp_dir_path)
                yield temp_dir_path
        else:
            yield profile_path
    else:
        yield None


def invoke_bolt(
        toolchain: ClangToolchain,
        obj_path: Path,
        bolt_log: TextIO,
        options: list[str] = []) -> None:
    bolt_path = toolchain.bolt()
    assert (bolt_path is not None)

    obj_path_bolted = extend_suffix(obj_path, ".bolt")

    bolt_log.write(f"BOLTing {str(obj_path)}\n")
    print(f"BOLTing {str(obj_path)}\n")
    bolt_log.flush()

    for (lib_prefix, func_names) in BOLT_SKIP_FUNCS.items():
        if obj_path.name.startswith(lib_prefix):
            options = options.copy()
            options.append(f"--skip-funcs={','.join(func_names)}")

    try:
        subprocess.run([bolt_path] + options + ["-o", obj_path_bolted, obj_path],
                       check=True,
                       stdout=bolt_log,
                       stderr=bolt_log)
    except subprocess.CalledProcessError as err:
        print(f"Failed to process object {str(obj_path)}")
        raise err

    bolt_log.write("\n")
    bolt_log.flush()

    obj_path.unlink()
    obj_path_bolted.rename(obj_path)


def process_objects(
        toolchain: ClangToolchain,
        root: Path,
        strip_only: bool,
        profile_generate: Optional[Path],
        profile_use: Optional[Path],
        bolt_log: TextIO) -> None:

    print("Processing objects")

    instrumentation_subjects = reify_singleton_patterns(root, BOLT_INSTRUMENTATION_SUBJECTS)
    optimization_subjects = get_prebuilt_binary_paths(root, toplevel_only=True)

    for obj_path in get_prebuilt_binary_paths(root, subdirs=["bin", "lib"]):
        print(f"Boltifyer is looking at object {str(obj_path)}")

        if not strip_only and obj_path in optimization_subjects:
            print(f"Object {str(obj_path)} is an optimization subject")
            options = ["--peepholes=all"]
            if obj_path in instrumentation_subjects:
                if profile_generate:
                    fdata_path = profile_generate / PROFILE_SUBDIR_BOLT / obj_path.name
                    options += [
                        "--instrument",
                        f"--instrumentation-file={fdata_path}",
                        "--instrumentation-file-append-pid",
                    ]

                elif profile_use:
                    fdata_path = profile_use / PROFILE_SUBDIR_BOLT / (obj_path.name + ".fdata")

                    if fdata_path.exists():
                        options += [
                            f"--data={fdata_path}",
                            "--reorder-blocks=ext-tsp",
                            "--reorder-functions=hfsort",
                            "--split-functions",
                            "--split-all-cold",
                            "--split-eh",
                            "--dyno-stats",
                        ]
                    else:
                        print(f"Profile data missing for {obj_path.relative_to(root)}")

            invoke_bolt(toolchain, obj_path, bolt_log, options)

        else:
            print(f"Object {str(obj_path)} is NOT an optimization subject\n")
            toolchain.strip_symbols(obj_path)


def boltify_toolchain(
        input_path: Path,
        dist_path: Path,
        build_name: str,
        strip_only: bool = False,
        profile_generate: Path | None = None,
        profile_use: Path | None = None,
        toolchain: ClangToolchain = CLANG_TOOLCHAIN_HOST) -> None:
    with (dist_path / BOLT_LOG_NAME).open("w") as bolt_log:
        with handle_input_path(input_path) as input_dir_path:
            print_fs_tree(input_dir_path)

            with expand_profiles(profile_use) as profile_use_path:
                if profile_use_path is not None:
                    print_fs_tree(profile_use_path)

                    version_file_path = profile_use_path / PROFILE_SUBDIR_BOLT / PROFILED_VERSION_FILENAME
                    if version_file_path.exists():
                        with open(version_file_path) as version_file:
                            profiled_version = version_file.read()
                            input_toolchain = RustToolchain(
                                input_dir_path, host=build_platform.system())
                            if input_toolchain.get_version() != profiled_version:
                                raise ScriptException(
                                    "Profiled compiler and input compiler versions do not match")

                try:
                    process_objects(
                        toolchain,
                        input_dir_path,
                        strip_only,
                        profile_generate,
                        profile_use_path,
                        bolt_log)
                    bolt_log.flush()
                except subprocess.CalledProcessError as err:
                    print("Error BOLTing prebuilt objects")
                    raise err

                print(f"Creating BOLTed archive")
                try:
                    archive_create(dist_path / f"rust-{build_name}", input_dir_path, overwrite=True)
                except subprocess.CalledProcessError as err:
                    print("Error creating the BOLTed archive")
                    raise err


def main() -> None:
    if not build_platform.is_linux():
        raise ScriptException("BOLT tools are only available on Linux hosts")

    args = parse_args()

    initialize_clang_prebuilt(args)

    boltify_toolchain(
        args.archive_path,
        args.dist_path,
        args.build_name,
        args.strip_only,
        args.profile_generate or args.profile_generate_relative,
        args.profile_use)

    if args.profile_use is not None and args.profile_use.name.endswith(
            ".tar.xz") and args.profile_use.parent != args.dist_path:
        shutil.copy2(args.profile_use, args.dist_path)


if __name__ == "__main__":
    try:
        main()

    except (ScriptException, argparse.ArgumentTypeError) as err:
        print_colored(str(err), TERM_RED)
        sys.exit(1)
