"""Template library manager.

Manages the global template library at ``~/.impakt/templates/``.
"""

from __future__ import annotations

import logging
from pathlib import Path
from typing import Iterator

from impakt.template.model import TemplateSpec

logger = logging.getLogger(__name__)

DEFAULT_LIBRARY_PATH = Path.home() / ".impakt" / "templates"


class TemplateLibrary:
    """Manages templates in a directory."""

    def __init__(self, path: Path | None = None) -> None:
        self.path = path or DEFAULT_LIBRARY_PATH
        self.path.mkdir(parents=True, exist_ok=True)

    def list(self) -> list[str]:
        """List available template names."""
        names = []
        for f in sorted(self.path.glob("*.yaml")):
            names.append(f.stem)
        for f in sorted(self.path.glob("*.yml")):
            names.append(f.stem)
        return names

    def get(self, name: str) -> TemplateSpec:
        """Load a template by name.

        Raises FileNotFoundError if not found.
        """
        for ext in (".yaml", ".yml"):
            path = self.path / f"{name}{ext}"
            if path.exists():
                return TemplateSpec.load(path)
        raise FileNotFoundError(f"Template not found: {name} (searched in {self.path})")

    def save(self, template: TemplateSpec) -> Path:
        """Save a template to the library.

        Returns the path where it was saved.
        """
        filename = template.name.lower().replace(" ", "_") + ".yaml"
        path = self.path / filename
        template.save(path)
        logger.info("Saved template '%s' to %s", template.name, path)
        return path

    def delete(self, name: str) -> bool:
        """Delete a template from the library."""
        for ext in (".yaml", ".yml"):
            path = self.path / f"{name}{ext}"
            if path.exists():
                path.unlink()
                logger.info("Deleted template '%s'", name)
                return True
        return False

    def __iter__(self) -> Iterator[TemplateSpec]:
        for name in self.list():
            try:
                yield self.get(name)
            except Exception as e:
                logger.warning("Failed to load template '%s': %s", name, e)

    def __len__(self) -> int:
        return len(self.list())

    def __contains__(self, name: str) -> bool:
        return name in self.list()
