"""
数据源管理工具 (工具 1-6)
"""

import logging

from ._base import register_tool, ToolDef

logger = logging.getLogger(__name__)


@register_tool("list_datasources")
class ListDatasourcesTool(ToolDef):
    name = "list_datasources"
    description = "获取数据源列表，支持搜索和状态筛选"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceName": {"type": "string", "description": "数据源名称模糊搜索"},
            "status": {"type": "integer", "description": "0=运行中, 1=已停止, 不传=全部"},
            "sourceType": {"type": "string", "enum": ["builtin", "external"], "description": "数据源类型"},
            "pageNum": {"type": "integer", "default": 1, "description": "页码"},
            "pageSize": {"type": "integer", "default": 20, "description": "每页数量"},
        },
        "required": [],
    }

    async def execute(self, args: dict) -> dict:
        params = {k: v for k, v in args.items() if v is not None}
        return await self.client.get("/datasource/connection/list", params=params)


@register_tool("get_datasource_detail")
class GetDatasourceDetailTool(ToolDef):
    name = "get_datasource_detail"
    description = "获取单个数据源的完整详情（含配置和实时结构）"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        ds_id = args["datasourceId"]
        result = {}
        # 获取基本信息
        try:
            result["detail"] = await self.client.get(f"/datasource/connection/{ds_id}")
        except Exception as e:
            result["detail"] = {"error": str(e)}
        # 获取配置
        try:
            result["config"] = await self.client.get(f"/datasource/config/{ds_id}")
        except Exception as e:
            result["config"] = {"error": str(e)}
        # 获取实时结构
        try:
            result["structure"] = await self.client.get(f"/datasource/connection/realtime/structure/{ds_id}")
        except Exception as e:
            result["structure"] = {"error": str(e)}
        return result


@register_tool("create_datasource")
class CreateDatasourceTool(ToolDef):
    name = "create_datasource"
    description = "创建外部数据源连接（可选先测试连接）"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceName": {"type": "string", "description": "数据源名称（3-20字）"},
            "datasourceType": {"type": "string", "enum": ["mysql", "postgresql", "oracle", "sqlserver", "dameng", "kingbase", "sqlite", "mariadb"], "description": "数据库类型"},
            "host": {"type": "string", "description": "数据库地址"},
            "port": {"type": "integer", "description": "端口号"},
            "databaseName": {"type": "string", "description": "要连接的数据库名"},
            "username": {"type": "string", "description": "数据库用户名"},
            "password": {"type": "string", "description": "密码"},
            "remark": {"type": "string", "description": "数据源描述"},
            "connectionType": {"type": "string", "enum": ["user_password", "ssl"], "description": "连接类型，默认 user_password"},
            "test_first": {"type": "boolean", "default": True, "description": "是否先测试连接，默认 true"},
        },
        "required": ["datasourceName", "datasourceType", "host", "port", "databaseName", "username"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        test_first = args.pop("test_first", True)
        
        # 如果需要先测试连接（测试失败时 client 会直接抛异常，由上层统一捕获）
        if test_first:
            test_data = {
                "datasourceName": args.get("datasourceName"),
                "datasourceType": args.get("datasourceType"),
                "host": args.get("host"),
                "port": args.get("port"),
                "databaseName": args.get("databaseName"),
                "username": args.get("username"),
                "password": args.get("password"),
                "connectionType": args.get("connectionType", "user_password"),
            }
            await self.client.post("/datasource/connection/test", json_data=test_data)

        # 创建数据源
        return await self.client.post("/datasource/connection", json_data=args)


@register_tool("update_datasource")
class UpdateDatasourceTool(ToolDef):
    name = "update_datasource"
    description = "更新数据源连接信息"
    input_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "string", "description": "数据源 ID"},
            "datasourceName": {"type": "string", "description": "更新名称"},
            "datasourceType": {"type": "string", "enum": ["mysql", "postgresql", "oracle", "sqlserver", "dameng", "kingbase", "sqlite", "mariadb"], "description": "数据库类型"},
            "host": {"type": "string", "description": "更新地址"},
            "port": {"type": "integer", "description": "更新端口"},
            "databaseName": {"type": "string", "description": "更新数据库名"},
            "username": {"type": "string", "description": "更新用户名"},
            "password": {"type": "string", "description": "新密码（不传则不变）"},
            "connectionType": {"type": "string", "enum": ["user_password", "ssl"], "description": "连接类型"},
            "remark": {"type": "string", "description": "更新描述"},
        },
        "required": ["id"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.put("/datasource/connection", json_data=args)


@register_tool("toggle_datasource_status")
class ToggleDatasourceStatusTool(ToolDef):
    name = "toggle_datasource_status"
    description = "启用/停用数据源"
    input_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "string", "description": "数据源 ID"},
            "status": {"type": "integer", "enum": [0, 1], "description": "0=启用, 1=停用"},
        },
        "required": ["id", "status"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.put("/datasource/connection/changeStatus", json_data=args)


@register_tool("delete_datasource")
class DeleteDatasourceTool(ToolDef):
    name = "delete_datasource"
    description = "删除数据源（运行中会自动先停用）"
    input_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "string", "description": "数据源 ID"},
        },
        "required": ["id"],
    }

    async def execute(self, args: dict) -> dict:
        ds_id = args["id"]
        # 先尝试停用（仅忽略已停用等预期错误）
        try:
            await self.client.put("/datasource/connection/changeStatus", json_data={"id": ds_id, "status": 1})
        except Exception as e:
            # 记录日志但继续删除
            logger.debug(f"停用数据源失败（可能已停用）: {e}")

        # 删除数据源
        return await self.client.delete(f"/datasource/connection/{ds_id}")


@register_tool("test_connection")
class TestConnectionTool(ToolDef):
    name = "test_connection"
    description = "测试外部数据库连接是否可用（不创建数据源）"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceType": {"type": "string", "enum": ["mysql", "postgresql", "oracle", "sqlserver", "dameng", "kingbase", "sqlite", "mariadb"], "description": "数据库类型"},
            "host": {"type": "string", "description": "数据库地址"},
            "port": {"type": "integer", "description": "端口号"},
            "databaseName": {"type": "string", "description": "要连接的数据库名"},
            "username": {"type": "string", "description": "数据库用户名"},
            "password": {"type": "string", "description": "密码"},
            "connectionType": {"type": "string", "enum": ["user_password", "ssl"], "description": "连接类型，默认 user_password"},
        },
        "required": ["datasourceType", "host", "port", "databaseName", "username"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        args.setdefault("connectionType", "user_password")
        return await self.client.post("/datasource/connection/test", json_data=args)


@register_tool("get_realtime_structure")
class GetRealtimeStructureTool(ToolDef):
    name = "get_realtime_structure"
    description = "拉取数据源真实的库表结构（实时探测远端数据库）"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        ds_id = args["datasourceId"]
        return await self.client.get(f"/datasource/connection/realtime/structure/{ds_id}")


@register_tool("create_builtin_datasource")
class CreateBuiltinDatasourceTool(ToolDef):
    name = "create_builtin_datasource"
    description = "创建内置 PostgreSQL 数据源连接，返回 connectionId（内置源建库建表链路第一步）"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceName": {"type": "string", "description": "数据源名称（3-20字）"},
            "remark": {"type": "string", "description": "数据源描述"},
        },
        "required": ["datasourceName"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.post("/datasource/connection/create_builtin_postgresql", json_data=args)


@register_tool("update_builtin_datasource")
class UpdateBuiltinDatasourceTool(ToolDef):
    name = "update_builtin_datasource"
    description = "修改内置 PostgreSQL 数据源连接信息"
    input_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "string", "description": "数据源 ID"},
            "datasourceName": {"type": "string", "description": "更新名称"},
            "remark": {"type": "string", "description": "更新描述"},
        },
        "required": ["id"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.put("/datasource/connection/update_builtin_database", json_data=args)
