from __future__ import annotations

import asyncio
from unittest.mock import MagicMock

from langchain_core.messages import ToolMessage

from deerflow.agents.middlewares.sensitive_output_redaction_middleware import SensitiveOutputRedactionMiddleware


def _request(name: str = "bash", args: dict | None = None):
    req = MagicMock()
    req.tool_call = {"name": name, "args": args or {}, "id": "call_1"}
    return req


def test_redacts_key_value_and_bearer():
    mw = SensitiveOutputRedactionMiddleware()
    req = _request()
    handler = MagicMock(
        return_value=ToolMessage(
            content="OPENAI_API_KEY=sk-abc123456789\nAuthorization: Bearer abcdefghijklmnop",
            tool_call_id="call_1",
            name="bash",
            status="success",
        )
    )
    result = mw.wrap_tool_call(req, handler)
    assert "OPENAI_API_KEY=[REDACTED]" in result.content
    assert "Bearer [REDACTED]" in result.content


def test_redacts_private_key_block():
    mw = SensitiveOutputRedactionMiddleware()
    req = _request()
    handler = MagicMock(
        return_value=ToolMessage(
            content="-----BEGIN PRIVATE KEY-----\nabc\n-----END PRIVATE KEY-----",
            tool_call_id="call_1",
            name="bash",
            status="success",
        )
    )
    result = mw.wrap_tool_call(req, handler)
    assert result.content == "[REDACTED]"


def test_async_path_redacts_jwt():
    mw = SensitiveOutputRedactionMiddleware()
    req = _request()

    async def handler(_):
        return ToolMessage(
            content="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.abcde12345.zyxwv98765",
            tool_call_id="call_1",
            name="bash",
            status="success",
        )

    result = asyncio.run(mw.awrap_tool_call(req, handler))
    assert result.content == "[REDACTED]"

