#!/usr/bin/env python3
"""Builds Fuchsia VIM3 firmware and creates CIPD package files.

In case CIPD is not available it is expected that all necessary tools would be
in PATH.

Clang and GCC from CIPD are used for repeatable build.
"""

import argparse
import logging
import os
import shutil
import subprocess
import sys
import textwrap
from pathlib import Path
from typing import Optional

_MY_DIR = Path(__file__).parent.resolve()

_BUILD_SCRIPT_TARGET = [_MY_DIR / "mk", "kvim3_zircon"]

_CIPD_DEPS_DIR = _MY_DIR / "cipd_deps"


def build():
    """Builds the CIPD package."""

    # Pass compilers for u-boot host tools build
    host_clang = _CIPD_DEPS_DIR / "clang"
    build_env = dict(
        os.environ,
        # Build bootloader binaries and generate combined images (as part of the signing process).
        CONFIG_AML_SIGNED_UBOOT="y",
        # Clang target for host tools
        TARGET="x86_64-unknown-linux-gnu",
        HOST_CLANG=host_clang,
        HOSTCC=host_clang / "bin" / "clang",
        HOSTCXX=host_clang / "bin" / "clang++",
        HOSTLD=host_clang / "bin" / "lld",
        CROSS_COMPILE="aarch64-elf-",
    )

    subprocess.run(
        _BUILD_SCRIPT_TARGET,
        env=build_env,
        check=True,
    )


def _parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument(
        "--cipd", default="cipd", help="Path to CIPD tool; looks on $PATH by default"
    )
    parser.add_argument(
        "--clean-cipd",
        action="store_true",
        help="Clear CIPD dependencies dir before start",
    )

    return parser.parse_args()


# list_of_packages are in format:
# [(dir name in cipd_deps, CIPD package path, package version, dir to add to PATH),...]
def ensure_deps(cipd_tool: str, list_of_packages):
    """Ensures that build deps have been downloaded.
    We should rely on as few host dependencies as possible, instead fetching
    what we need from CIPD to ensure a hermetic and reproducible build env.
    """

    try:
        for (name, cipd_package, cipd_version, path_dir) in list_of_packages:
            dep_dir = _CIPD_DEPS_DIR / name
            subprocess.run(
                [cipd_tool, "ensure", "-root", dep_dir, "-ensure-file", "-"],
                check=True,
                text=True,
                input=f"{cipd_package} {cipd_version}",
            )
            _add_path_prefix(dep_dir / path_dir)
    except FileNotFoundError as err:
        print(f"WARNING: CIPD tool was likely not found: {err}.")
        print("WARNING: Relying on system tools for the build.")


def _add_path_prefix(path):
    """Adds |path| to the beginning of $PATH."""
    os.environ["PATH"] = str(path) + os.pathsep + os.environ["PATH"]


def cipd_dep_dir_clean():
    logging.info(f"Removing CIPD deps dir: {_CIPD_DEPS_DIR}")
    shutil.rmtree(_CIPD_DEPS_DIR, ignore_errors=True)


def fuchsia_build(cipd, clean_cipd):
    if clean_cipd:
        cipd_dep_dir_clean()

    # Versions are pinned to current integration version in most cases.
    # It is done to prevent unexpected breaking when integration moves forward.
    # It is required to do manual testing before bumping the versions.
    list_of_packages = [
        ("make", "fuchsia/third_party/make/linux-amd64", "version:4.3", "bin"),
        # gcc version is 15.2.1,2.46.50
        (
            "gcc",
            "fuchsia/third_party/gcc/linux-amd64",
            "git_revision:26e4f8ad7220f692cd8010f9cf7620d690f1b094,1daba1c5ceb27d25265ba2801f5be307d21a6abd",
            "bin",
        ),
        (
            "gcc-arm-none-eabi",
            "pigweed/third_party/gcc-arm-none-eabi/linux-amd64",
            "version:10-2020-q4-major",
            "bin",
        ),
        # For host u-boot tools
        (
            "clang",
            "fuchsia/third_party/clang/linux-amd64",
            "git_revision:80743bd43fd5b38fedc503308e7a652e23d3ec93",
            "bin",
        ),
        # Host zip tool for signing
        (
            "zip",
            "skia/bots/zip_linux-amd64",
            "version:0",
            "",
        ),
        # Host xxd tool for signing
        (
            "xxd",
            "fuchsia/third_party/xxd/linux-amd64",
            "version:2@9.1.1061",
            "",
        ),
    ]
    ensure_deps(cipd, list_of_packages)

    build()


def _main() -> int:
    logging.basicConfig(level=logging.INFO)
    args = _parse_args()

    fuchsia_build(
        cipd=args.cipd,
        clean_cipd=args.clean_cipd,
    )


if __name__ == "__main__":
    sys.exit(_main())
