#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

from common import (
    backup_config,
    dump_json,
    load_openclaw_config,
    ensure_agent_entry,
    make_result,
    validate_json,
)


def toggle_tool(
    agent_id: str,
    tool_name: str,
    action: str,
    config_path: Path | None = None,
    dry_run: bool = False,
) -> dict:
    resolved_path = config_path or Path("~/.openclaw/openclaw.json").expanduser().resolve()
    config = load_openclaw_config(resolved_path)
    entry = ensure_agent_entry(config, agent_id)

    entry.setdefault("tools", {})
    if not isinstance(entry["tools"], dict):
        entry["tools"] = {}
    tools_deny: list[str] = list(entry["tools"].get("deny", []) or [])

    if action == "enable":
        if tool_name not in tools_deny:
            return make_result(
                "enable_tool",
                agent_id,
                "tools.deny",
                before=tools_deny,
                after=tools_deny,
                changed=False,
                message=f"tool '{tool_name}' 已经处于启用状态（不在 deny 列表中），无需操作",
            )
        new_deny = [t for t in tools_deny if t != tool_name]
        result = make_result(
            "enable_tool",
            agent_id,
            "tools.deny",
            before=tools_deny,
            after=new_deny,
            changed=True,
            dry_run=dry_run,
            message=f"将启用 tool: {tool_name}（从 deny 列表移除）",
        )
    elif action == "disable":
        if tool_name in tools_deny:
            return make_result(
                "disable_tool",
                agent_id,
                "tools.deny",
                before=tools_deny,
                after=tools_deny,
                changed=False,
                message=f"tool '{tool_name}' 已经处于禁用状态（已在 deny 列表中），无需操作",
            )
        new_deny = tools_deny + [tool_name]
        result = make_result(
            "disable_tool",
            agent_id,
            "tools.deny",
            before=tools_deny,
            after=new_deny,
            changed=True,
            dry_run=dry_run,
            message=f"将禁用 tool: {tool_name}（加入 deny 列表）",
        )
    else:
        raise ValueError(f"无效的 action: {action}，请使用 enable 或 disable")

    if dry_run or not result["changed"]:
        return result

    entry["tools"]["deny"] = new_deny
    if not validate_json(config):
        entry["tools"]["deny"] = tools_deny
        raise ValueError("配置 JSON 校验失败，变更已回滚，openclaw.json 未被修改")

    backup_path = backup_config(resolved_path)
    dump_json(resolved_path, config)
    result["backup"] = str(backup_path)
    return result


def main() -> int:
    parser = argparse.ArgumentParser(description="启用或禁用 Agent 的某个 tool")
    parser.add_argument("--agent-id", required=True, help="Agent ID")
    parser.add_argument("--tool-name", required=True, help="tool 名称")
    parser.add_argument(
        "--action", required=True, choices=["enable", "disable"], help="enable=启用（移出 deny）, disable=禁用（加入 deny）"
    )
    parser.add_argument("--dry-run", action="store_true", help="仅预览变更，不实际写入")
    parser.add_argument(
        "--config",
        help="openclaw.json 路径（默认 ~/.openclaw/openclaw.json）",
    )
    args = parser.parse_args()

    try:
        config_path = Path(args.config).expanduser().resolve() if args.config else None
        result = toggle_tool(args.agent_id, args.tool_name, args.action, config_path, args.dry_run)
        json.dump(result, sys.stdout, indent=2, ensure_ascii=False)
        sys.stdout.write("\n")
        return 0
    except (FileNotFoundError, ValueError) as e:
        error = {
            "error": str(e),
            "agent_id": args.agent_id,
            "tool_name": args.tool_name,
            "action": args.action,
        }
        json.dump(error, sys.stdout, indent=2, ensure_ascii=False)
        sys.stdout.write("\n")
        return 1


if __name__ == "__main__":
    raise SystemExit(main())