import pytest

from feid.agent import AgenteMaestroNASA
from feid.core import ConfigAgente
import feid.agent.maestro as maestro_module


class DummyThread:
    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs

    def start(self):
        return None


class StrictAgent(AgenteMaestroNASA):
    def _technical_work(self, task):
        return f"ok:{task}"


@pytest.fixture
def strict_agent(monkeypatch):
    monkeypatch.setattr(maestro_module.threading, "Thread", DummyThread)
    config = ConfigAgente(protocol_strict_mode=True, max_workers=0)
    return StrictAgent("STRICT", config=config, auto_persist=False)


@pytest.fixture
def relaxed_agent(monkeypatch):
    monkeypatch.setattr(maestro_module.threading, "Thread", DummyThread)
    config = ConfigAgente(protocol_strict_mode=False, max_workers=0)
    return StrictAgent("RELAXED", config=config, auto_persist=False)


def test_strict_mode_rejects_invalid_fipa(strict_agent):
    msg = {"performative": "invalid", "content": "x", "sender": "a", "receiver": "b"}
    _, ack = strict_agent.receive_message(msg, return_ack=True)
    assert ack["status"] == "REJECTED"
    assert "Invalid FIPA" in ack["reason"]


def test_strict_mode_accepts_valid_fipa(strict_agent):
    msg = {"performative": "request", "content": "x", "sender": "a", "receiver": "b"}
    task_id, ack = strict_agent.receive_message(msg, return_ack=True)
    assert task_id is not None
    assert ack["status"] == "ACCEPTED"


def test_strict_mode_rejects_invalid_kqml(strict_agent):
    msg = {"verb": "unknown", "content": "x"}
    _, ack = strict_agent.receive_message(msg, return_ack=True)
    assert ack["status"] == "REJECTED"
    assert "Invalid KQML" in ack["reason"]


def test_strict_mode_accepts_valid_kqml(strict_agent):
    msg = {"verb": "tell", "content": "x"}
    task_id, ack = strict_agent.receive_message(msg, return_ack=True)
    assert task_id is not None
    assert ack["status"] == "ACCEPTED"


def test_strict_mode_rejects_invalid_jsonrpc(strict_agent):
    msg = {"jsonrpc": "2.0", "method": "m"}
    _, ack = strict_agent.receive_message(msg, return_ack=True)
    assert ack["status"] == "REJECTED"
    assert "Missing JSON-RPC" in ack["reason"]


def test_strict_mode_accepts_valid_jsonrpc(strict_agent):
    msg = {"jsonrpc": "2.0", "id": 1, "method": "m", "params": {"a": 1}}
    task_id, ack = strict_agent.receive_message(msg, return_ack=True)
    assert task_id is not None
    assert ack["status"] == "ACCEPTED"


def test_relaxed_mode_accepts_invalid_fipa(relaxed_agent):
    msg = {"performative": "invalid", "content": "x"}
    task_id, ack = relaxed_agent.receive_message(msg, return_ack=True)
    assert task_id is not None
    assert ack["status"] == "ACCEPTED"


def test_relaxed_mode_accepts_invalid_kqml(relaxed_agent):
    msg = {"verb": "unknown", "content": "x"}
    task_id, ack = relaxed_agent.receive_message(msg, return_ack=True)
    assert task_id is not None
    assert ack["status"] == "ACCEPTED"


def test_relaxed_mode_accepts_invalid_jsonrpc(relaxed_agent):
    msg = {"jsonrpc": "2.0", "method": "m"}
    task_id, ack = relaxed_agent.receive_message(msg, return_ack=True)
    assert task_id is not None
    assert ack["status"] == "ACCEPTED"
