# [DEF:DebugPluginModule:Module]
# @SEMANTICS: plugin, debug, api, database, superset
# @PURPOSE: Implements a plugin for system diagnostics and debugging Superset API responses.
# @LAYER: Plugins
# @RELATION: Inherits from PluginBase. Uses SupersetClient from core.
# @CONSTRAINT: Must use belief_scope for logging.

# [SECTION: IMPORTS]
from typing import Dict, Any, Optional
from ..core.plugin_base import PluginBase
from ..core.superset_client import SupersetClient
from ..core.logger import logger, belief_scope
# [/SECTION]

# [DEF:DebugPlugin:Class]
# @PURPOSE: Plugin for system diagnostics and debugging.
class DebugPlugin(PluginBase):
    """
    Plugin for system diagnostics and debugging.
    """

    @property
    # [DEF:id: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"
    # [/DEF:id:Function]

    @property
    # [DEF:name: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"
    # [/DEF:name:Function]

    @property
    # [DEF:description: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."
    # [/DEF:description:Function]

    @property
    # [DEF:version: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"
    # [/DEF:version:Function]

    @property
    # [DEF:ui_route: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"
    # [/DEF:ui_route:Function]

    # [DEF:get_schema: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"]
        }
    # [/DEF:get_schema:Function]

    # [DEF:execute:Function]
    # @PURPOSE: Executes the debug logic.
    # @PARAM: params (Dict[str, Any]) - Debug parameters.
    # @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]) -> Dict[str, Any]:
        with belief_scope("execute"):
            action = params.get("action")
            
            if action == "test-db-api":
                return await self._test_db_api(params)
            elif action == "get-dataset-structure":
                return await self._get_dataset_structure(params)
            else:
                raise ValueError(f"Unknown action: {action}")
    # [/DEF:execute:Function]

    # [DEF:_test_db_api: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.
    # @RETURN:  Dict - Comparison results.
    async def _test_db_api(self, params: Dict[str, Any]) -> 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]:
            env_config = config_manager.get_environment(name)
            if not env_config:
                raise ValueError(f"Environment '{name}' not found.")
            
            client = SupersetClient(env_config)
            client.authenticate()
            count, dbs = client.get_databases()
            results[name] = {
                "count": count,
                "databases": dbs
            }
            
        return results
    # [/DEF:_test_db_api:Function]

    # [DEF:_get_dataset_structure: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.
    # @RETURN:  Dict - Dataset structure.
    async def _get_dataset_structure(self, params: Dict[str, Any]) -> 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")

        from ..dependencies import get_config_manager
        config_manager = get_config_manager()
        env_config = config_manager.get_environment(env_name)
        if not env_config:
            raise ValueError(f"Environment '{env_name}' not found.")
            
        client = SupersetClient(env_config)
        client.authenticate()
        
        dataset_response = client.get_dataset(dataset_id)
        return dataset_response.get('result') or {}
    # [/DEF:_get_dataset_structure:Function]

# [/DEF:DebugPlugin:Class]
# [/DEF:DebugPluginModule:Module]