from types import SimpleNamespace

from minisweagent.exceptions import FormatError
from minisweagent.models.test_models import DeterministicToolcallModel, make_toolcall_output
from minisweagent.models.utils.actions_toolcall import parse_toolcall_actions


def make_fake_tool_call(call_id: str, name: str, arguments: str) -> SimpleNamespace:
    return SimpleNamespace(
        id=call_id,
        function=SimpleNamespace(name=name, arguments=arguments),
    )


raw_tool_call = make_fake_tool_call("call_1", "bash", '{"command": "pwd"}')
actions = parse_toolcall_actions([raw_tool_call], format_error_template="{{ error }}")

wire_tool_calls = [
    {
        "id": raw_tool_call.id,
        "type": "function",
        "function": {
            "name": raw_tool_call.function.name,
            "arguments": raw_tool_call.function.arguments,
        },
    }
]
model = DeterministicToolcallModel(
    outputs=[make_toolcall_output("I will inspect", wire_tool_calls, actions)],
    cost_per_call=0,
    observation_template="code={{ output.returncode }}; text={{ output.output | trim }}; lesson={{ lesson }}",
)

assistant_message = model.query([{"role": "user", "content": "Where am I?"}])
fake_outputs = [{"output": "/tmp/demo\n", "returncode": 0, "exception_info": ""}]
observation = model.format_observation_messages(
    assistant_message,
    fake_outputs,
    template_vars={"lesson": "offline"},
)[0]

print("action:", actions[0])
print("assistant:", assistant_message["content"])
print("observation:", observation["role"], observation["tool_call_id"], observation["content"])

try:
    parse_toolcall_actions(
        [make_fake_tool_call("call_bad", "read_file", '{"command": "README.md"}')],
        format_error_template="{{ error }}",
    )
except FormatError as signal:
    message = signal.messages[0]
    print("format-error:", message["role"], message["extra"]["interrupt_type"], message["content"])
