from __future__ import annotations

import pytest
import respx
import httpx

from surfinguard import Guard, Policy
from surfinguard.exceptions import NotAllowedError
from surfinguard.integrations.autogen import SurfinguardAutoGenGuard

import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from conftest import SAFE_RESPONSE, DANGER_RESPONSE


@pytest.fixture()
def mock_api():
    with respx.mock(base_url="https://test.surfinguard.com", assert_all_called=False) as api:
        yield api


@pytest.fixture()
def guard():
    return Guard(
        api_key="sg_test_0123456789abcdef0123456789abcdef",
        base_url="https://test.surfinguard.com",
        policy=Policy.MODERATE,
    )


class TestAutoGenGuard:
    def test_wrap_function_allows_safe(self, mock_api, guard):
        mock_api.post("/v2/check").mock(
            return_value=httpx.Response(200, json=SAFE_RESPONSE)
        )
        ag_guard = SurfinguardAutoGenGuard(guard)

        @ag_guard.wrap_function("command")
        def execute(cmd: str) -> str:
            return f"executed: {cmd}"

        result = execute("ls -la")
        assert result == "executed: ls -la"

    def test_wrap_function_blocks_dangerous(self, mock_api, guard):
        mock_api.post("/v2/check").mock(
            return_value=httpx.Response(200, json=DANGER_RESPONSE)
        )
        ag_guard = SurfinguardAutoGenGuard(guard)

        @ag_guard.wrap_function("command")
        def execute(cmd: str) -> str:
            return f"executed: {cmd}"

        with pytest.raises(NotAllowedError):
            execute("rm -rf /")

    def test_check_message_string(self, mock_api, guard):
        route = mock_api.post("/v2/check").mock(
            return_value=httpx.Response(200, json=SAFE_RESPONSE)
        )
        ag_guard = SurfinguardAutoGenGuard(guard)
        ag_guard.check_message("Hello, how are you?")
        assert route.called
        import json
        body = json.loads(route.calls[0].request.content)
        assert body["type"] == "text"

    def test_check_message_dict(self, mock_api, guard):
        route = mock_api.post("/v2/check").mock(
            return_value=httpx.Response(200, json=SAFE_RESPONSE)
        )
        ag_guard = SurfinguardAutoGenGuard(guard)
        ag_guard.check_message({"role": "user", "content": "Do something"})
        assert route.called

    def test_check_message_ignores_none(self, mock_api, guard):
        route = mock_api.post("/v2/check").mock(
            return_value=httpx.Response(200, json=SAFE_RESPONSE)
        )
        ag_guard = SurfinguardAutoGenGuard(guard)
        ag_guard.check_message({"role": "system"})
        assert not route.called
