"""验证每个 ``*Callback`` 子类的 ``callback_type`` 正确，且子类是 ``PassiveCallback`` 派生。"""

from __future__ import annotations

import pytest

from linksoul_agentsdk.agent_sdk import AgentSdk
from linksoul_agentsdk.enums import AgentCallbackType
from linksoul_agentsdk.passive import (
    Asr2LlmCallback,
    Asr2TtsCallback,
    AsrVideo2TtsCallback,
    AsrVideo2VlmCallback,
    Audio2LlmCallback,
    Audio2TtsCallback,
    AudioVideo2TtsCallback,
    AudioVideo2VlmCallback,
    PassiveCallback,
)


_SECRET = "0123456789abcdef0123456789abcdef"


@pytest.fixture
def sdk():
    return AgentSdk.create("wss://example.invalid/v1", "app", "test-app-key", _SECRET)


@pytest.mark.parametrize(
    "cls, expected",
    [
        (Audio2LlmCallback, AgentCallbackType.AUDIO_2_LLM),
        (Audio2TtsCallback, AgentCallbackType.AUDIO_2_TTS),
        (Asr2LlmCallback, AgentCallbackType.ASR_2_LLM),
        (Asr2TtsCallback, AgentCallbackType.ASR_2_TTS),
        (AsrVideo2VlmCallback, AgentCallbackType.ASR_VIDEO_2_VLM),
        (AsrVideo2TtsCallback, AgentCallbackType.ASR_VIDEO_2_TTS),
        (AudioVideo2VlmCallback, AgentCallbackType.AUDIO_VIDEO_2_VLM),
        (AudioVideo2TtsCallback, AgentCallbackType.AUDIO_VIDEO_2_TTS),
    ],
)
def test_callback_type_assigned(sdk, cls, expected):
    instance = cls(sdk)
    assert instance.callback_type is expected
    assert isinstance(instance, PassiveCallback)


def test_base_default_methods_dont_raise(sdk):
    from linksoul_agentsdk.agent_param import AgentParam
    from linksoul_agentsdk.passive.base import GreetResponse
    from tests.conftest import FakeLinkskyClient

    class Concrete(Audio2LlmCallback):
        def on_request(self, *_args, **_kwargs):
            pass

    cb = Concrete(sdk)
    # base 类提供的 5 个共享方法都不能抛
    cb.on_robot_online("A", sdk.get_agent_meta("missing") or _empty_meta())
    cb.on_robot_offline("A")
    cb.on_face_info("A", "ev", AgentParam())
    cb.on_video_frame("A", "ev", 2, None, False, -1, AgentParam())
    fake = FakeLinkskyClient(sdk)
    cb.on_greet_signal("A", "ev", AgentParam(), GreetResponse(fake, "A", "cid"))
    cb.on_state("A", "ev", "battery", "80")


def _empty_meta():
    from linksoul_agentsdk.agent_meta import AgentMeta
    return AgentMeta()
