"""
Coolify Plugin — Clean Architecture

AI-driven deployment management for Coolify instances.
Modular handlers for applications, deployments, and servers.
"""

from typing import Any

from plugins.base import BasePlugin
from plugins.coolify import handlers
from plugins.coolify.client import CoolifyClient


class CoolifyPlugin(BasePlugin):
    """
    Coolify project plugin — Clean architecture.

    Provides Coolify deployment management capabilities including:
    - Application management (CRUD, lifecycle, env vars, logs)
    - Database management (PostgreSQL, MySQL, MariaDB, MongoDB, Redis, ClickHouse, backups)
    - Deployment control (list, cancel, deploy by tag/UUID)
    - Project & environment management (CRUD)
    - Server management (CRUD, resources, domains, validation)
    - Service management (CRUD, lifecycle, env vars)
    """

    @staticmethod
    def get_plugin_name() -> str:
        """Return plugin type identifier."""
        return "coolify"

    @staticmethod
    def get_required_config_keys() -> list[str]:
        """Return required configuration keys."""
        return ["url", "token"]

    def __init__(self, config: dict[str, Any], project_id: str | None = None):
        """
        Initialize Coolify plugin with handlers.

        Args:
            config: Configuration dictionary containing:
                - url: Coolify instance URL
                - token: API token for Bearer authentication
            project_id: Optional project ID (auto-generated if not provided)
        """
        super().__init__(config, project_id=project_id)

        self.client = CoolifyClient(
            site_url=config["url"],
            token=config["token"],
        )

    @staticmethod
    def get_tool_specifications() -> list[dict[str, Any]]:
        """
        Return all tool specifications for ToolGenerator.

        Returns:
            List of tool specification dictionaries
        """
        specs = []

        specs.extend(handlers.applications.get_tool_specifications())
        specs.extend(handlers.databases.get_tool_specifications())
        specs.extend(handlers.deployments.get_tool_specifications())
        specs.extend(handlers.projects.get_tool_specifications())
        specs.extend(handlers.servers.get_tool_specifications())
        specs.extend(handlers.services.get_tool_specifications())

        return specs

    def __getattr__(self, name: str):
        """
        Dynamically delegate method calls to appropriate handlers.

        Args:
            name: Method name being called

        Returns:
            Handler function from the appropriate handler module
        """
        handler_modules = [
            handlers.applications,
            handlers.databases,
            handlers.deployments,
            handlers.projects,
            handlers.servers,
            handlers.services,
        ]

        for module in handler_modules:
            if hasattr(module, name):
                func = getattr(module, name)

                async def wrapper(_func=func, **kwargs):
                    return await _func(self.client, **kwargs)

                return wrapper

        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")

    async def health_check(self) -> dict[str, Any]:
        """
        Check if Coolify instance is accessible.

        Returns:
            Dict containing health check result
        """
        try:
            await self.client.request("GET", "version")
            return {"healthy": True, "message": "Coolify instance is accessible"}
        except Exception as e:
            return {"healthy": False, "message": f"Coolify health check failed: {str(e)}"}
