#!/usr/bin/env python3
"""
Append an include-tree comment after the contents of each `memmap*.ld` under
`src/*/pico_platform/`.

The comment matches the output of `memmap_include_tree.py` (two columns, no color).
Re-running replaces a previous block marked `BEGIN_MEMMAP_INCLUDE_TREE` /
`END_MEMMAP_INCLUDE_TREE` (at the end of the file, or at the beginning for older runs).

Examples:

    ./tools/memmap_annotate.py # annotates all memmap*.ld files in the SDK

    ./tools/memmap_annotate.py --ci # does not write files; exits with failure if any memmap would need updating
"""

from __future__ import annotations

import argparse
import re
import sys
from pathlib import Path

_TOOLS = Path(__file__).resolve().parent
if str(_TOOLS) not in sys.path:
    sys.path.insert(0, str(_TOOLS))

import memmap_include_tree as inc_tree

_ANNOT_BEGIN = "/* BEGIN_MEMMAP_INCLUDE_TREE\n"
_ANNOT_END = " * END_MEMMAP_INCLUDE_TREE */\n"
_ANNOT_BLOCK_CORE = (
    r"/\* BEGIN_MEMMAP_INCLUDE_TREE\n.*?\n \* END_MEMMAP_INCLUDE_TREE \*/\s*"
)


def strip_annotation_block(text: str) -> str:
    """Remove a previously inserted annotation block (trailing, or legacy leading)."""
    t = text
    # Preferred: block at end of file
    m = re.search(_ANNOT_BLOCK_CORE + r"\Z", t, re.DOTALL)
    if m:
        head = t[: m.start()].rstrip("\n")
        if head:
            head += "\n"
        return head
    # Legacy: block was prepended at the beginning
    m2 = re.match(_ANNOT_BLOCK_CORE + r"\n?", t, re.DOTALL)
    if m2:
        return t[m2.end() :].lstrip("\n")
    return t


def build_annotation_block(tree_lines: list[str]) -> str:
    parts = [
        _ANNOT_BEGIN,
        " * This is the default include tree for this file (generated by tools/memmap_annotate.py\n"
        " * and tools/memmap_include_tree.py). To override any files in this tree, see the\n"
        " * pico_add_linker_script_override_path CMake function under pico_standard_link.\n",
        " *\n",
    ]
    for ln in tree_lines:
        parts.append(" * " + ln + "\n")
    parts.append(_ANNOT_END)
    return "".join(parts)


def annotate_one(
    path: Path,
    sdk_root: Path,
    platform: str | None,
    *,
    ci: bool,
) -> tuple[bool, str]:
    """Return (ok, status message). ok is False on unresolved includes."""
    path = path.resolve()
    search_dirs = inc_tree.default_search_dirs(sdk_root, path, platform)
    visited: set[Path] = set()
    user_l_set: frozenset[Path] = frozenset()
    user_l_labels: dict[Path, str] = {}
    root_node, root_children = inc_tree.walk_includes(
        path, search_dirs, user_l_set, user_l_labels, visited
    )
    missing = inc_tree.collect_unresolved_include_paths(root_children)
    if missing:
        names = ", ".join(m.name for m in missing)
        return False, f"unresolved INCLUDE: {names}"

    lines = inc_tree.format_tree_lines(root_node, root_children, color=False)
    block = build_annotation_block(lines)
    old = path.read_text(encoding="utf-8", errors="replace")
    body = strip_annotation_block(old)
    if body and not body.endswith("\n"):
        body += "\n"
    new = body + "\n" + block if body else block
    if new == old:
        return True, "unchanged"
    if ci:
        return True, "needs updating"
    path.write_text(new, encoding="utf-8")
    return True, "updated"


def parse_args(argv: list[str]) -> argparse.Namespace:
    p = argparse.ArgumentParser(
        description=inc_tree.fold_docstring_for_argparse(__doc__ or ""),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    p.add_argument(
        "--sdk-root",
        type=Path,
        default=None,
        help=inc_tree.CLI_HELP_SDK_ROOT,
    )
    p.add_argument(
        "--platform",
        default=None,
        metavar="CHIP",
        help=inc_tree.CLI_HELP_PLATFORM,
    )
    p.add_argument(
        "--ci",
        action="store_true",
        help="Do not write files; exit with failure if any memmap would need updating",
    )
    p.add_argument(
        "paths",
        nargs="*",
        type=Path,
        metavar="MEMMAP.LD",
        help="Linker scripts to annotate (default: all src/*/pico_platform/memmap*.ld)",
    )
    return p.parse_args(argv)


def main(argv: list[str]) -> int:
    args = parse_args(argv)
    sdk_root = args.sdk_root
    if args.paths:
        files = [p.resolve() for p in args.paths]
        for f in files:
            if not f.is_file():
                print(f"error: not a file: {f}", file=sys.stderr)
                return 1
        if sdk_root is None:
            sdk_root = inc_tree.infer_sdk_root(files[0])
        if sdk_root is None:
            print(inc_tree.CLI_MSG_SDK_ROOT_INFER_FAILED, file=sys.stderr)
            return 1
    else:
        if sdk_root is None:
            sdk_root = inc_tree.infer_sdk_root(Path.cwd())
        if sdk_root is None:
            print(inc_tree.CLI_MSG_SDK_ROOT_INFER_FAILED, file=sys.stderr)
            return 1
        files = sorted(sdk_root.glob("src/*/pico_platform/memmap*.ld"))

    if not files:
        print("error: no memmap*.ld files to process", file=sys.stderr)
        return 1

    sdk_root = sdk_root.resolve()
    if args.platform is not None:
        perr = inc_tree.validate_explicit_platform(sdk_root, args.platform)
        if perr:
            print(f"error: {perr}", file=sys.stderr)
            return 1

    err = 0
    for f in files:
        plat = args.platform or inc_tree.infer_platform_chip(f)
        ok, msg = annotate_one(f, sdk_root, plat, ci=args.ci)
        try:
            tag = str(f.relative_to(sdk_root))
        except ValueError:
            tag = str(f)
        if ok:
            print(inc_tree.format_memmap_annotate_status_line(tag, msg))
            if args.ci and msg == "needs updating":
                err = 1
        else:
            print(f"{tag}: {msg}", file=sys.stderr)
            err = 1
    return err


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))
