"""AiCippy workspace reference folder manager.

Creates and manages the ``aicippy-ref/`` directory in the working project.
This folder centralises all agent-generated artefacts so they stay out of
the user's source tree while remaining version-controllable.

Directory layout::

    aicippy-ref/
    ├── .gitignore          # ignores temp/, keeps everything else
    ├── memory/             # agent memory files (workspace context, patterns)
    ├── agentic/            # agent execution logs, plans, reasoning traces
    ├── temp/               # ephemeral scratch files (gitignored)
    ├── scripts/            # generated helper scripts
    └── docs/               # generated markdown docs, session summaries
"""

from __future__ import annotations

from pathlib import Path
from typing import Final

from aicippy.utils.logging import get_logger

logger = get_logger(__name__)

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------

REF_FOLDER_NAME: Final[str] = "aicippy-ref"

_SUBDIRS: Final[list[str]] = [
    "memory",
    "agentic",
    "temp",
    "scripts",
    "docs",
]

_GITIGNORE_CONTENT: Final[str] = """\
# AiCippy reference folder
# Temp files are ephemeral — always ignored
temp/

# OS junk
.DS_Store
Thumbs.db
"""

_README_CONTENT: Final[str] = """\
# aicippy-ref

Auto-generated workspace reference folder for **AiCippy** agents.

| Folder     | Purpose                                           |
|------------|---------------------------------------------------|
| `memory/`  | Agent memory files — workspace context & patterns |
| `agentic/` | Execution logs, plans, and reasoning traces       |
| `temp/`    | Ephemeral scratch files (git-ignored)             |
| `scripts/` | Generated helper scripts                          |
| `docs/`    | Session summaries, generated markdown docs        |

> This folder is managed by AiCippy. Safe to commit to version control.
> The `temp/` subfolder is always git-ignored.
"""


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------


def create_ref_folder(project_root: Path) -> Path:
    """Create the ``aicippy-ref/`` directory tree under *project_root*.

    Idempotent — existing directories and files are preserved.

    Returns:
        Path to the created ``aicippy-ref/`` folder.

    """
    ref_dir = project_root / REF_FOLDER_NAME

    # Create root + subdirectories
    for sub in _SUBDIRS:
        (ref_dir / sub).mkdir(parents=True, exist_ok=True)

    # Write .gitignore (only if missing — never overwrite user edits)
    gitignore_path = ref_dir / ".gitignore"
    if not gitignore_path.exists():
        gitignore_path.write_text(_GITIGNORE_CONTENT, encoding="utf-8")

    # Write README.md (only if missing)
    readme_path = ref_dir / "README.md"
    if not readme_path.exists():
        readme_path.write_text(_README_CONTENT, encoding="utf-8")

    logger.info(
        "ref_folder_created",
        path=str(ref_dir),
        subdirs=_SUBDIRS,
    )
    return ref_dir


def get_ref_folder(project_root: Path) -> Path | None:
    """Return the ``aicippy-ref/`` path if it exists, else ``None``."""
    ref_dir = project_root / REF_FOLDER_NAME
    return ref_dir if ref_dir.is_dir() else None


def ensure_ref_folder(project_root: Path) -> Path:
    """Return existing ``aicippy-ref/`` or create it.

    Convenience wrapper that combines :func:`get_ref_folder` and
    :func:`create_ref_folder`.
    """
    ref_dir = get_ref_folder(project_root)
    if ref_dir is not None:
        return ref_dir
    return create_ref_folder(project_root)


def get_memory_dir(project_root: Path) -> Path:
    """Return ``aicippy-ref/memory/`` path, creating if needed."""
    ref_dir = ensure_ref_folder(project_root)
    mem_dir = ref_dir / "memory"
    mem_dir.mkdir(parents=True, exist_ok=True)
    return mem_dir


def get_agentic_dir(project_root: Path) -> Path:
    """Return ``aicippy-ref/agentic/`` path, creating if needed."""
    ref_dir = ensure_ref_folder(project_root)
    ag_dir = ref_dir / "agentic"
    ag_dir.mkdir(parents=True, exist_ok=True)
    return ag_dir


def get_temp_dir(project_root: Path) -> Path:
    """Return ``aicippy-ref/temp/`` path, creating if needed."""
    ref_dir = ensure_ref_folder(project_root)
    tmp_dir = ref_dir / "temp"
    tmp_dir.mkdir(parents=True, exist_ok=True)
    return tmp_dir


def get_scripts_dir(project_root: Path) -> Path:
    """Return ``aicippy-ref/scripts/`` path, creating if needed."""
    ref_dir = ensure_ref_folder(project_root)
    scr_dir = ref_dir / "scripts"
    scr_dir.mkdir(parents=True, exist_ok=True)
    return scr_dir


def get_docs_dir(project_root: Path) -> Path:
    """Return ``aicippy-ref/docs/`` path, creating if needed."""
    ref_dir = ensure_ref_folder(project_root)
    doc_dir = ref_dir / "docs"
    doc_dir.mkdir(parents=True, exist_ok=True)
    return doc_dir
