"""CLI entrypoints for copying packaged agentic assets into a target directory."""

from __future__ import annotations

import shutil
import sys
from importlib import resources
from importlib.resources import as_file
from pathlib import Path
from tempfile import TemporaryDirectory

import agentic_toolbelt

PAYLOAD_DIR_ITEMS = (".agents", ".codex", ".github", ".tasks", "templates")
DEFAULT_AGENTS_TEMPLATE = "AGENTS.md"
TARGET_AGENTS_NAME = "AGENTS.md"
REQUIRED_PAYLOAD_SUBPATHS = (
    ".agents/skills",
    ".agents/tasks",
    ".tasks",
    ".codex/skills",
    "templates/codex/config.toml.example",
    "templates/codex/routing-profiles.toml",
    "templates/codex/agents",
)
RUNTIME_CODEX_ITEMS = (
    ("templates/codex/config.toml.example", ".codex/config.toml"),
    ("templates/codex/agents", ".codex/agents"),
)


def _validate_payload(source_root) -> None:
    for raw_path in REQUIRED_PAYLOAD_SUBPATHS:
        path = source_root.joinpath(*raw_path.split("/"))
        if not path.exists():
            raise FileNotFoundError(
                f"Incomplete installed payload: missing packaged path '{raw_path}'. "
                "Reinstall or upgrade agentic-toolbelt, then rerun agentic-set."
            )


def _copy_item(
    source_path: Path,
    destination_path: Path,
    *,
    temp_root: Path,
    force: bool,
) -> bool:
    if destination_path.exists():
        if not force:
            return False

        if destination_path.is_dir() and not destination_path.is_symlink():
            shutil.rmtree(destination_path)
        else:
            destination_path.unlink()

    if source_path.is_dir():
        temp_path = temp_root / destination_path.name
        if temp_path.exists():
            shutil.rmtree(temp_path)
        temp_path.parent.mkdir(parents=True, exist_ok=True)
        shutil.copytree(source_path, temp_path)
        destination_path.parent.mkdir(parents=True, exist_ok=True)
        temp_path.replace(destination_path)
    else:
        destination_path.parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(source_path, destination_path)

    return True


def copy_payload(
    destination: Path,
    force: bool = False,
    agents_template: str = DEFAULT_AGENTS_TEMPLATE,
) -> tuple[list[str], list[str]]:
    """Copy packaged payload items to ``destination``.

    Returns two lists: copied item names and skipped item names.
    """

    copied: list[str] = []
    skipped: list[str] = []

    payload_items = [(item, item) for item in PAYLOAD_DIR_ITEMS]
    payload_items.append((agents_template, TARGET_AGENTS_NAME))
    payload_items.extend(RUNTIME_CODEX_ITEMS)

    with TemporaryDirectory(prefix="agentic-set-", dir=destination) as temp_root_str:
        temp_root = Path(temp_root_str)
        with as_file(resources.files(agentic_toolbelt)) as source_root:
            _validate_payload(source_root)
            for source_name, destination_name in payload_items:
                source_path = source_root / source_name
                if not source_path.exists():
                    raise FileNotFoundError(f"Missing packaged payload item: {source_name}")

                destination_path = destination / destination_name
                if _copy_item(
                    source_path,
                    destination_path,
                    temp_root=temp_root,
                    force=force,
                ):
                    copied.append(destination_name)
                else:
                    skipped.append(destination_name)

    return copied, skipped


def build_parser(prog: str, description: str) -> "argparse.ArgumentParser":
    import argparse

    parser = argparse.ArgumentParser(
        prog=prog,
        description=description,
    )
    parser.add_argument(
        "--force",
        action="store_true",
        help="Overwrite existing files/directories if they already exist.",
    )
    return parser


def run_cli(
    argv: list[str] | None,
    *,
    prog: str,
    description: str,
    agents_template: str,
) -> int:
    parser = build_parser(prog=prog, description=description)
    args = parser.parse_args(argv)
    destination = Path.cwd()
    destination.mkdir(parents=True, exist_ok=True)

    try:
        copied, skipped = copy_payload(
            destination,
            force=args.force,
            agents_template=agents_template,
        )
    except Exception as exc:  # pragma: no cover - exercised via CLI behavior
        print(f"{prog}: {exc}", file=sys.stderr)
        return 1

    for item in copied:
        print(f"copied {item} -> {destination / item}")
    for item in skipped:
        print(f"skipped {item} (already exists; use --force to overwrite)")

    return 0


def main(argv: list[str] | None = None) -> int:
    return run_cli(
        argv,
        prog="agentic-set",
        description="Copy packaged agent payload assets into the current directory.",
        agents_template=DEFAULT_AGENTS_TEMPLATE,
    )


if __name__ == "__main__":  # pragma: no cover
    raise SystemExit(main())
