"""Plugin system for framework-specific integrations.

This module provides the core plugin infrastructure according to PRD-002.
Plugins encapsulate framework-specific integrations like ORMs, auth, caching, etc.
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from pathlib import Path
from typing import TYPE_CHECKING, Any, ClassVar

import msgspec

if TYPE_CHECKING:
    from litestar_start.core.base import GeneratorContext


class PluginMetadata(msgspec.Struct):
    """Metadata for a plugin."""

    name: str
    display_name: str
    category: str
    description: str
    version: str = "0.1.0"
    author: str = ""
    requires: list[str] = []  # Other plugin names
    conflicts: list[str] = []  # Incompatible plugins


class PluginFile(msgspec.Struct):
    """Represents a file to be generated by a plugin."""

    path: str  # Relative path from project root
    content: str | None = None  # Direct content (mutually exclusive with template)
    template: str | None = None  # Template name to render
    mode: str = "create"  # 'create', 'append', 'prepend', 'merge', 'replace'


class PluginResult(msgspec.Struct):
    """Result of applying a plugin."""

    files: list[PluginFile] = []
    dependencies: list[str] = []
    dev_dependencies: list[str] = []
    env_vars: dict[str, str] = {}
    scripts: dict[str, str] = {}  # pyproject.toml scripts


class PluginInterface(ABC):
    """Base interface for all plugins."""

    metadata: ClassVar[PluginMetadata]

    def __init__(self, context: GeneratorContext) -> None:
        """Initialize plugin with context.

        Args:
            context: Generator context with project configuration.

        """
        self.context = context
        self._template_dir = Path(__file__).parent / "templates"

    @abstractmethod
    def apply(self) -> PluginResult:
        """Generate plugin files and return result.

        Returns:
            PluginResult with files, dependencies, env vars, etc.

        """
        ...

    def get_template_context(self) -> dict[str, Any]:
        """Additional context for template rendering.

        Returns:
            Dictionary of template variables specific to this plugin.

        """
        return {}

    def validate(self) -> list[str]:
        """Validate plugin can be applied.

        Returns:
            List of validation error messages. Empty list if valid.

        """
        return []

    def post_apply(self) -> None:
        """Run hook called after all plugins are applied.

        Override this to perform post-processing tasks.
        """
        return
