"""Thin CLI wrappers that match the `llm-*` Makefile targets used in tabm-style repos."""

from __future__ import annotations

import argparse
import logging
import sys

from collections.abc import Sequence

from kestrel_llm.logging_utils import setup_logging
from kestrel_llm.repo_utils import resolve_repo_root_and_llm_file
from kestrel_llm.update_llm_symbols import update_llm_file
from kestrel_llm.verify_llm_docs import VerifyOptions, verify


def _build_common_parser(*, prog: str, description: str) -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog=prog, description=description)
    parser.add_argument(
        "--repo-root",
        default=None,
        help="Repository root (default: search upward for LLM.txt, else $CONDOR_REPO_ROOT, else CWD).",
    )
    parser.add_argument(
        "--llm-file",
        default=None,
        help="Path to LLM.txt (default: detected alongside repo root).",
    )
    parser.add_argument(
        "--exclude-dir",
        action="append",
        default=[],
        help="Additional directory names to exclude during scanning (repeatable).",
    )
    parser.add_argument(
        "--log-level",
        default=None,
        help="Logging level (e.g. INFO, WARNING). Overrides LOG_LEVEL env var.",
    )
    return parser


def llm_check_main(argv: Sequence[str] | None = None) -> int:
    """Entry-point for the `llm-check` console script."""
    parser = _build_common_parser(
        prog="llm-check",
        description="Verify LLM.txt covers all Python files (strict: 2-sentence summaries + sorted sections).",
    )
    args = parser.parse_args(argv)
    setup_logging(args.log_level)

    repo_root, llm_file = resolve_repo_root_and_llm_file(
        repo_root=args.repo_root, llm_file=args.llm_file
    )

    return verify(
        repo_root=repo_root,
        llm_file_path=llm_file,
        options=VerifyOptions(
            enforce_two_sentences=False,
            enforce_exact_two_sentences=True,
            extra_excluded_dirs=tuple(args.exclude_dir),
            warn_unsorted=False,
            enforce_sorted=True,
            fix_sorting=True,
        ),
    )


def llm_fix_main(argv: Sequence[str] | None = None) -> int:
    """Entry-point for the `llm-fix` console script."""
    parser = _build_common_parser(
        prog="llm-fix",
        description="Sort LLM.txt sections and refresh autogenerated Symbols blocks.",
    )
    args = parser.parse_args(argv)
    setup_logging(args.log_level)

    repo_root, llm_file = resolve_repo_root_and_llm_file(
        repo_root=args.repo_root, llm_file=args.llm_file
    )

    # Match the tabm Makefile semantics: stop if sorting+verification fails.
    exit_code = verify(
        repo_root=repo_root,
        llm_file_path=llm_file,
        options=VerifyOptions(
            enforce_two_sentences=False,
            enforce_exact_two_sentences=False,
            extra_excluded_dirs=tuple(args.exclude_dir),
            warn_unsorted=False,
            enforce_sorted=False,
            fix_sorting=True,
        ),
    )
    if exit_code != 0:
        return exit_code

    try:
        update_llm_file(
            repo_root=repo_root, llm_file_path=llm_file, include_line_numbers=True
        )
    except Exception as e:  # pragma: no cover
        logging.getLogger("llm_fix").error("Failed to update Symbols blocks: %s", e)
        return 1

    return 0


def llm_sync_main(argv: Sequence[str] | None = None) -> int:
    """Entry-point for the `llm-sync` console script."""
    parser = _build_common_parser(
        prog="llm-sync",
        description="Fix sorting, strictly verify LLM.txt rules, refresh Symbols blocks, then strictly verify again.",
    )
    args = parser.parse_args(argv)
    setup_logging(args.log_level)

    repo_root, llm_file = resolve_repo_root_and_llm_file(
        repo_root=args.repo_root, llm_file=args.llm_file
    )

    # 1) Sort + basic verify (matches Makefile: `verify_llm_docs.py --fix-sorting`)
    exit_code = verify(
        repo_root=repo_root,
        llm_file_path=llm_file,
        options=VerifyOptions(
            enforce_two_sentences=False,
            enforce_exact_two_sentences=False,
            extra_excluded_dirs=tuple(args.exclude_dir),
            warn_unsorted=False,
            enforce_sorted=False,
            fix_sorting=True,
        ),
    )
    if exit_code != 0:
        return exit_code

    # 2) Strict verify (exactly two sentences, sorted)
    exit_code = verify(
        repo_root=repo_root,
        llm_file_path=llm_file,
        options=VerifyOptions(
            enforce_two_sentences=False,
            enforce_exact_two_sentences=True,
            extra_excluded_dirs=tuple(args.exclude_dir),
            warn_unsorted=False,
            enforce_sorted=True,
            fix_sorting=True,
        ),
    )
    if exit_code != 0:
        return exit_code

    # 3) Refresh Symbols blocks
    try:
        update_llm_file(
            repo_root=repo_root, llm_file_path=llm_file, include_line_numbers=True
        )
    except Exception as e:  # pragma: no cover
        logging.getLogger("llm_sync").error("Failed to update Symbols blocks: %s", e)
        return 1

    # 4) Strict verify again
    return verify(
        repo_root=repo_root,
        llm_file_path=llm_file,
        options=VerifyOptions(
            enforce_two_sentences=False,
            enforce_exact_two_sentences=True,
            extra_excluded_dirs=tuple(args.exclude_dir),
            warn_unsorted=False,
            enforce_sorted=True,
            fix_sorting=True,
        ),
    )


if __name__ == "__main__":  # pragma: no cover
    # Provide a small hint when executed directly.
    sys.stderr.write(
        "This module provides console scripts: llm-check, llm-fix, llm-sync.\n"
    )
    sys.exit(2)
