"""Command-line entry point for the Accountable Record staged pipeline.

May include convenience aliases:

uv run accountable-record check
uv run accountable-record build-catalog
uv run accountable-record export
uv run accountable-record resolve-packages
uv run accountable-record write-lock
uv run accountable-record verify-lock
uv run accountable-record validate-generated
uv run accountable-record render-docs
"""

import argparse
from pathlib import Path
import sys

from accountable_record.commands.write_lock import write_lock_command
from accountable_record.pipeline.context import PipelineRunContext
from accountable_record.pipeline.runner import run_through
from accountable_record.pipeline.stages import valid_stage_targets


def build_parser() -> argparse.ArgumentParser:
    """Build the command-line argument parser for the AR pipeline CLI."""
    parser = argparse.ArgumentParser(prog="accountable-record")

    parser.add_argument(
        "--target",
        dest="target_root",
        type=Path,
        default=None,
        help="Target repository root to validate. Defaults to the current directory.",
    )
    parser.add_argument(
        "--no-strict",
        action="store_true",
        help="Run without strict validation mode.",
    )

    sub = parser.add_subparsers(dest="command", required=True)

    run = sub.add_parser("run", help="Run pipeline stages.")
    run.add_argument(
        "stage",
        choices=valid_stage_targets(),
        help="Stage code (s010..s090) or 'all'.",
    )

    # Verb aliases map to running through the stage that owns that concern.
    sub.add_parser("check", help="Run all stages (alias for run all).")
    sub.add_parser("build-catalog", help="Run through catalog (s050).")
    sub.add_parser("export", help="Run through exports (s060).")
    sub.add_parser("resolve-packages", help="Run through resolution (s070).")
    sub.add_parser("verify-lock", help="Verify existing resolution locks (s070).")
    sub.add_parser("validate-generated", help="Run through generated (s080).")
    sub.add_parser("render-docs", help="Run through docs (s090).")

    # write-lock is NOT a verification alias. It is a mutating write-intent
    # command: it runs read-only through s060 to establish state, then writes
    # data/locks/. It is routed outside _VERB_TARGETS for that reason, and must
    # not route through s070 (s070 verifies existing locks; it does not create
    # them as a side effect).
    sub.add_parser(
        "write-lock", help="Write resolution locks (mutates the repository)."
    )

    return parser


# Read-only verb aliases. Each maps to running the read-only pipeline through
# the stage that owns that concern. write-lock is deliberately absent: it is a
# mutating command, handled explicitly in main().
_VERB_TARGETS: dict[str, str] = {
    "check": "all",
    "build-catalog": "s050",
    "export": "s060",
    "resolve-packages": "s070",
    "verify-lock": "s070",
    "validate-generated": "s080",
    "render-docs": "s090",
}


def main(argv: list[str] | None = None) -> int:
    """Main entry point for the AR pipeline CLI."""
    parser = build_parser()
    args = parser.parse_args(argv)

    context = PipelineRunContext.from_target(
        args.target_root,
        strict=not args.no_strict,
    )

    if args.command == "run":
        return run_through(args.stage, context)

    # write-lock is the one mutating verb; it does not route through the
    # read-only _VERB_TARGETS table.
    if args.command == "write-lock":
        return write_lock_command(context)

    stage = _VERB_TARGETS.get(args.command)
    if stage is None:
        parser.error(f"Unknown command {args.command!r}")
        return 2

    return run_through(stage, context)


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