"""
Base Plugin Types

Provides core types for the plugin system including:
- Plugin interface
- Hook definitions
- Configuration structures
"""

import logging
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any, Callable, Optional

logger = logging.getLogger(__name__)


class PluginStatus(Enum):
    """Plugin lifecycle status"""

    UNLOADED = "unloaded"
    LOADED = "loaded"
    ACTIVE = "active"
    DISABLED = "disabled"
    ERROR = "error"


class HookType(Enum):
    """Types of hooks available"""

    # File operations
    BEFORE_READ = "before_read"
    AFTER_READ = "after_read"
    BEFORE_WRITE = "before_write"
    AFTER_WRITE = "after_write"
    BEFORE_EDIT = "before_edit"
    AFTER_EDIT = "after_edit"
    BEFORE_DELETE = "before_delete"
    AFTER_DELETE = "after_delete"

    # Bash operations
    BEFORE_BASH = "before_bash"
    AFTER_BASH = "after_bash"

    # Agent operations
    BEFORE_AGENT_RUN = "before_agent_run"
    AFTER_AGENT_RUN = "after_agent_run"
    ON_AGENT_ERROR = "on_agent_error"

    # Session operations
    ON_SESSION_START = "on_session_start"
    ON_SESSION_END = "on_session_end"

    # Tool operations
    BEFORE_TOOL_EXECUTE = "before_tool_execute"
    AFTER_TOOL_EXECUTE = "after_tool_execute"


@dataclass
class HookContext:
    """Context passed to hook functions"""

    hook_type: HookType
    data: dict[str, Any] = field(default_factory=dict)
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass
class HookResult:
    """Result from a hook execution"""

    success: bool
    modified_data: Optional[dict[str, Any]] = None
    should_continue: bool = True
    error: Optional[str] = None


# Type alias for hook functions
HookFunction = Callable[[HookContext], HookResult]


@dataclass
class Hook:
    """Hook definition"""

    hook_type: HookType
    handler: HookFunction
    priority: int = 0
    plugin_name: Optional[str] = None


@dataclass
class PluginInfo:
    """Plugin metadata"""

    name: str
    version: str
    description: str = ""
    author: str = ""
    homepage: str = ""
    license: str = ""
    keywords: list[str] = field(default_factory=list)
    dependencies: list[str] = field(default_factory=list)


@dataclass
class PluginConfig:
    """Plugin configuration"""

    path: Path
    enabled: bool = True
    settings: dict[str, Any] = field(default_factory=dict)
    hooks_enabled: list[HookType] = field(default_factory=list)


class Plugin(ABC):
    """
    Base class for plugins

    Plugins can:
    - Register hooks for lifecycle events
    - Define custom tools
    - Extend groknroll functionality

    Example:
        class MyPlugin(Plugin):
            @property
            def info(self) -> PluginInfo:
                return PluginInfo(name="my-plugin", version="1.0.0")

            def activate(self) -> None:
                self.register_hook(HookType.BEFORE_WRITE, self.on_before_write)

            def on_before_write(self, ctx: HookContext) -> HookResult:
                # Modify or validate before write
                return HookResult(success=True)
    """

    def __init__(self):
        self._status = PluginStatus.UNLOADED
        self._hooks: list[Hook] = []
        self._tools: list[Any] = []

    @property
    @abstractmethod
    def info(self) -> PluginInfo:
        """Plugin metadata"""
        pass

    @property
    def status(self) -> PluginStatus:
        """Current plugin status"""
        return self._status

    @property
    def hooks(self) -> list[Hook]:
        """Registered hooks"""
        return self._hooks

    @property
    def tools(self) -> list[Any]:
        """Custom tools defined by plugin"""
        return self._tools

    def activate(self) -> None:
        """
        Called when plugin is activated

        Override to register hooks and setup resources.
        """
        pass

    def deactivate(self) -> None:
        """
        Called when plugin is deactivated

        Override to cleanup resources.
        """
        pass

    def register_hook(
        self,
        hook_type: HookType,
        handler: HookFunction,
        priority: int = 0,
    ) -> None:
        """
        Register a hook handler

        Args:
            hook_type: Type of hook to register for
            handler: Function to call when hook is triggered
            priority: Higher priority hooks run first
        """
        hook = Hook(
            hook_type=hook_type,
            handler=handler,
            priority=priority,
            plugin_name=self.info.name,
        )
        self._hooks.append(hook)

    def unregister_hook(self, hook_type: HookType) -> None:
        """
        Unregister all hooks of a type

        Args:
            hook_type: Type of hook to unregister
        """
        self._hooks = [h for h in self._hooks if h.hook_type != hook_type]

    def register_tool(self, tool: Any) -> None:
        """
        Register a custom tool

        Args:
            tool: Tool instance (must inherit from BaseTool)
        """
        self._tools.append(tool)
