# #region DebugPluginModule [TYPE Module] [SEMANTICS debug, diagnostic, superset, api, system]
# @BRIEF Implements a plugin for system diagnostics and debugging Superset API responses.
# @LAYER Plugin
# @BRIEF Plugin for diagnostics. Inherits PluginBase.
# @RELATION DEPENDS_ON -> [TaskContext]

from typing import Any

from ..core.logger import belief_scope, logger
from ..core.plugin_base import PluginBase
from ..core.superset_client import SupersetClient
from ..core.task_manager.context import TaskContext


# #region DebugPlugin [TYPE Class]
# @BRIEF Plugin for system diagnostics and debugging.
class DebugPlugin(PluginBase):
    """
    Plugin for system diagnostics and debugging.
    """

    @property
    # region id [TYPE Function]
    # @PURPOSE: Returns the unique identifier for the debug plugin.
    # @PRE  Plugin instance exists.
    # @POST  Returns string ID.
    # @RETURN  str - "system-debug"
    def id(self) -> str:
        with belief_scope("id"):
            return "system-debug"
    # endregion id

    @property
    # region name [TYPE Function]
    # @PURPOSE: Returns the human-readable name of the debug plugin.
    # @PRE  Plugin instance exists.
    # @POST  Returns string name.
    # @RETURN  str - Plugin name.
    def name(self) -> str:
        with belief_scope("name"):
            return "System Debug"
    # endregion name

    @property
    # region description [TYPE Function]
    # @PURPOSE: Returns a description of the debug plugin.
    # @PRE  Plugin instance exists.
    # @POST  Returns string description.
    # @RETURN  str - Plugin description.
    def description(self) -> str:
        with belief_scope("description"):
            return "Run system diagnostics and debug Superset API responses."
    # endregion description

    @property
    # region version [TYPE Function]
    # @PURPOSE: Returns the version of the debug plugin.
    # @PRE  Plugin instance exists.
    # @POST  Returns string version.
    # @RETURN  str - "1.0.0"
    def version(self) -> str:
        with belief_scope("version"):
            return "1.0.0"
    # endregion version

    @property
    # region ui_route [TYPE Function]
    # @PURPOSE: Returns the frontend route for the debug plugin.
    # @RETURN  str - "/tools/debug"
    def ui_route(self) -> str:
        with belief_scope("ui_route"):
            return "/tools/debug"
    # endregion ui_route

    # region get_schema [TYPE Function]
    # @PURPOSE: Returns the JSON schema for the debug plugin parameters.
    # @PRE  Plugin instance exists.
    # @POST  Returns dictionary schema.
    # @RETURN  Dict[str, Any] - JSON schema.
    def get_schema(self) -> dict[str, Any]:
        with belief_scope("get_schema"):
            return {
            "type": "object",
            "properties": {
                "action": {
                    "type": "string",
                    "title": "Action",
                    "enum": ["test-db-api", "get-dataset-structure"],
                    "default": "test-db-api"
                },
                "env": {
                    "type": "string",
                    "title": "Environment",
                    "description": "The Superset environment (for dataset structure)."
                },
                "dataset_id": {
                    "type": "integer",
                    "title": "Dataset ID",
                    "description": "The ID of the dataset (for dataset structure)."
                },
                "source_env": {
                    "type": "string",
                    "title": "Source Environment",
                    "description": "Source env for DB API test."
                },
                "target_env": {
                    "type": "string",
                    "title": "Target Environment",
                    "description": "Target env for DB API test."
                }
            },
            "required": ["action"]
        }
    # endregion get_schema

    # region execute [TYPE Function]
    # @PURPOSE: Executes the debug logic with TaskContext support.
    # @PARAM  params (Dict[str, Any]) - Debug parameters.
    # @PARAM  context (Optional[TaskContext]) - Task context for logging with source attribution.
    # @PRE  action must be provided in params.
    # @POST  Debug action is executed and results returned.
    # @RETURN  Dict[str, Any] - Execution results.
    async def execute(self, params: dict[str, Any], context: TaskContext | None = None) -> dict[str, Any]:
        with belief_scope("execute"):
            action = params.get("action")

            # Use TaskContext logger if available, otherwise fall back to app logger
            log = context.logger if context else logger
            debug_log = log.with_source("debug") if context else log
            superset_log = log.with_source("superset_api") if context else log

            debug_log.info(f"Executing debug action: {action}")

            if action == "test-db-api":
                return await self._test_db_api(params, superset_log)
            elif action == "get-dataset-structure":
                return await self._get_dataset_structure(params, superset_log)
            else:
                debug_log.error(f"Unknown action: {action}")
                raise ValueError(f"Unknown action: {action}")
    # endregion execute

    # region _test_db_api [TYPE Function]
    # @PURPOSE: Tests database API connectivity for source and target environments.
    # @PRE      source_env and target_env params exist in params.
    # @POST     Returns DB counts for both envs.
    # @PARAM    params (Dict) - Plugin parameters.
    # @PARAM    log - Logger instance for superset_api source.
    # @RETURN   Dict - Comparison results.
    async def _test_db_api(self, params: dict[str, Any], log) -> dict[str, Any]:
        with belief_scope("_test_db_api"):
            source_env_name = params.get("source_env")
            target_env_name = params.get("target_env")

            if not source_env_name or not target_env_name:
                raise ValueError("source_env and target_env are required for test-db-api")

            from ..dependencies import get_config_manager
            config_manager = get_config_manager()

            results = {}
            for name in [source_env_name, target_env_name]:
                log.info(f"Testing database API for environment: {name}")
                env_config = config_manager.get_environment(name)
                if not env_config:
                    log.error(f"Environment '{name}' not found.")
                    raise ValueError(f"Environment '{name}' not found.")

                client = SupersetClient(env_config)
                client.authenticate()
                count, dbs = client.get_databases()
                log.debug(f"Found {count} databases in {name}")
                results[name] = {
                    "count": count,
                    "databases": dbs
                }

            return results
    # endregion _test_db_api

    # region _get_dataset_structure [TYPE Function]
    # @PURPOSE: Retrieves the structure of a dataset.
    # @PRE      env and dataset_id params exist in params.
    # @POST     Returns dataset JSON structure.
    # @PARAM    params (Dict) - Plugin parameters.
    # @PARAM    log - Logger instance for superset_api source.
    # @RETURN   Dict - Dataset structure.
    async def _get_dataset_structure(self, params: dict[str, Any], log) -> dict[str, Any]:
        with belief_scope("_get_dataset_structure"):
            env_name = params.get("env")
            dataset_id = params.get("dataset_id")

            if not env_name or dataset_id is None:
                raise ValueError("env and dataset_id are required for get-dataset-structure")

            log.info(f"Fetching structure for dataset {dataset_id} in {env_name}")

            from ..dependencies import get_config_manager
            config_manager = get_config_manager()
            env_config = config_manager.get_environment(env_name)
            if not env_config:
                log.error(f"Environment '{env_name}' not found.")
                raise ValueError(f"Environment '{env_name}' not found.")

            client = SupersetClient(env_config)
            client.authenticate()

            dataset_response = client.get_dataset(dataset_id)
            log.debug(f"Retrieved dataset structure for {dataset_id}")
            return dataset_response.get('result') or {}
    # endregion _get_dataset_structure

# #endregion DebugPlugin
# #endregion DebugPluginModule
