import json

from onefirewall_ai.agent import loop


class DummySpinner:
    def stop(self):
        return None


class FakeResponse:
    def __init__(self, lines):
        self.status_code = 200
        self.headers = {"Content-Type": "text/event-stream"}
        self.text = ""
        self._lines = lines

    def iter_lines(self):
        return iter(self._lines)


def _build_sse_lines(text):
    payload = {
        "choices": [
            {
                "delta": {"content": text},
                "finish_reason": None,
            }
        ]
    }
    return [
        f"data: {json.dumps(payload)}".encode("utf-8"),
        b"data: [DONE]",
    ]


def test_stream_gateway_ignores_xml_tool_calls_without_tools(monkeypatch):
    captured_payload = {}
    xml = (
        '<function_calls><invoke name="bash">'
        '<parameter name="command">dir D:\\\\nexcode</parameter>'
        "</invoke></function_calls>"
    )

    def fake_post(url, headers, json, stream, timeout):
        captured_payload["json"] = json
        return FakeResponse(_build_sse_lines(xml))

    monkeypatch.setattr(loop._requests, "post", fake_post)
    loop._abort_flag.clear()

    response = loop._stream_gateway(
        endpoint="https://example.com",
        api_key="test-key",
        model="openai/gpt-4o",
        messages=[{"role": "user", "content": "check app.py"}],
        tools=[],
        spinner=DummySpinner(),
        token_callback=lambda _token: None,
    )

    assert "tools" not in captured_payload["json"]
    assert "tool_choice" not in captured_payload["json"]
    assert response.tool_calls == []


def test_stream_gateway_parses_xml_tool_calls_when_tools_are_enabled(monkeypatch):
    captured_payload = {}
    xml = (
        '<function_calls><invoke name="bash">'
        '<parameter name="command">dir D:\\\\nexcode</parameter>'
        "</invoke></function_calls>"
    )

    def fake_post(url, headers, json, stream, timeout):
        captured_payload["json"] = json
        return FakeResponse(_build_sse_lines(xml))

    monkeypatch.setattr(loop._requests, "post", fake_post)
    loop._abort_flag.clear()

    response = loop._stream_gateway(
        endpoint="https://example.com",
        api_key="test-key",
        model="openai/gpt-4o",
        messages=[{"role": "user", "content": "fix app.py"}],
        tools=[
            {
                "type": "function",
                "function": {
                    "name": "bash",
                    "description": "Run shell commands",
                    "parameters": {"type": "object", "properties": {}},
                },
            }
        ],
        spinner=DummySpinner(),
        token_callback=lambda _token: None,
    )

    assert captured_payload["json"]["tool_choice"] == "auto"
    assert response.tool_calls[0]["function"]["name"] == "bash"
    assert json.loads(response.tool_calls[0]["function"]["arguments"]) == {
        "command": "dir D:\\\\nexcode"
    }
