import json
from dataclasses import dataclass

import pytest

from frisk_sdk.framework_adapter.base_framework_adapter import BaseFrameworkAdapter
from frisk_sdk.framework_adapter.framework_adapter import NormalizedToolCall


@dataclass
class _DummyToolCall:
    name: str
    args: dict


def test_serialize_tool_args_roundtrip():
    adapter = BaseFrameworkAdapter()

    tool_args = {"a": 1, "nested": {"b": True}, "list": [1, 2, 3]}
    tool_args_serialized = adapter.serialize_tool_args(tool_args)

    assert isinstance(tool_args_serialized.value, str)
    assert json.loads(tool_args_serialized.value) == tool_args


def test_serialize_agent_state_roundtrip():
    adapter = BaseFrameworkAdapter()

    agent_state = {"user": {"id": 123, "role": "admin"}, "flags": ["x"]}
    s = adapter.serialize_agent_state(agent_state)

    assert isinstance(s.value, str)
    assert json.loads(s.value) == agent_state


def test_normalize_tool_call_extracts_fields_and_generates_id(
    monkeypatch: pytest.MonkeyPatch,
):
    adapter = BaseFrameworkAdapter()

    # Make id generation deterministic
    adapter._cuid_generator = lambda: "cuid-123"

    tool_call = _DummyToolCall(name="tool_a", args={"x": 1})

    info = adapter.normalize_tool_call(tool_call)

    assert isinstance(info, NormalizedToolCall)
    assert info.id == "cuid-123"
    assert info.name == "tool_a"
    assert info.args == {"x": 1}


def test_normalize_tool_call_generates_unique_ids_by_default():
    adapter = BaseFrameworkAdapter()

    tool_call = _DummyToolCall(name="tool_a", args={})

    id1 = adapter.normalize_tool_call(tool_call).id
    id2 = adapter.normalize_tool_call(tool_call).id

    # cuid2 should mint distinct ids across calls
    assert isinstance(id1, str) and id1
    assert isinstance(id2, str) and id2
    assert id1 != id2
