# Perseus Assistant Formats (Phase 24)
# ───────────────────────────────────

from datetime import datetime, timezone
from typing import NamedTuple


class FormatTarget(NamedTuple):
    """One assistant context-file format that Perseus can render."""

    name: str               # CLI name, e.g. "agents-md"
    description: str         # Human-readable description
    default_output: str      # Default filename written when --output is omitted
    assistants: list[str]    # Which assistants read this file

    # Optional wrapping — applied around the resolved markdown body
    header: str = ""         # Prepended before the resolved markdown
    footer: str = ""         # Appended after the resolved markdown


def _generated_header(version: str, source_hint: str = ".perseus/context.md") -> str:
    """Standard Perseus-generation marker."""
    now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
    return (
        f"> [!NOTE]\n"
        f"> This file is generated by [Perseus](https://github.com/tcconnally/perseus) v{version} on {now}.\n"
        f"> Edit `{source_hint}` instead, then run `perseus render --format <target>`.\n"
        f">\n"
    )


# ── Format registry ──────────────────────────────────────────────────────────

FORMAT_TARGETS: dict[str, FormatTarget] = {
    "agents-md": FormatTarget(
        name="agents-md",
        description="AGENTS.md — cross-tool agent instructions standard (Cursor, Aider, Codex, Zed, etc.)",
        default_output="AGENTS.md",
        assistants=["Cursor", "Aider", "Codex CLI", "Zed", "Phoenix", "Droids", "Factory"],
    ),
    "claude-md": FormatTarget(
        name="claude-md",
        description="CLAUDE.md — Anthropic Claude Code native context file",
        default_output="CLAUDE.md",
        assistants=["Claude Code"],
    ),
    "cursorrules": FormatTarget(
        name="cursorrules",
        description=".cursorrules — Cursor IDE project rules file",
        default_output=".cursorrules",
        assistants=["Cursor IDE"],
    ),
    "copilot-instructions": FormatTarget(
        name="copilot-instructions",
        description=".github/copilot-instructions.md — GitHub Copilot instructions",
        default_output=".github/copilot-instructions.md",
        assistants=["GitHub Copilot"],
    ),
}


def list_formats() -> list[dict]:
    """Return format targets as a list of dicts for CLI display."""
    return [
        {
            "name": ft.name,
            "description": ft.description,
            "default_output": ft.default_output,
            "assistants": ft.assistants,
        }
        for ft in FORMAT_TARGETS.values()
    ]


def wrap_rendered(body: str, fmt_name: str, version: str) -> str:
    """Wrap resolved markdown body with the target format's header/footer."""
    ft = FORMAT_TARGETS.get(fmt_name)
    if ft is None:
        return body
    header = ft.header or _generated_header(version)
    footer = ft.footer or ""
    return header + "\n" + body + ("\n" + footer if footer else "")


def get_default_output_path(fmt_name: str, workspace_dir: str | None = None) -> str:
    """Return the default absolute output path for a format target.

    When workspace_dir is given, resolves relative to it (e.g. AGENTS.md
    in the repo root).  Otherwise returns just the filename.
    """
    import os
    from pathlib import Path

    ft = FORMAT_TARGETS.get(fmt_name)
    if ft is None:
        return fmt_name  # fallback: use the name as-is

    if workspace_dir is not None:
        return str(Path(workspace_dir) / ft.default_output)
    return ft.default_output
