from types import SimpleNamespace

from app.runtime.extensions.plugin.registry import PluginRegistry
from app.schemas.plugin import PluginRuntimeStatus


def test_registry_owns_classes_instances_and_stable_snapshots():
    """注册表集中持有类与实例，快照不受后续热重载修改影响。"""
    registry = PluginRegistry()
    plugin_class = type("Demo", (), {})
    plugin_instance = SimpleNamespace(plugin_name="演示")
    registry.classes["Demo"] = plugin_class
    registry.running["Demo"] = plugin_instance

    snapshot = registry.running_snapshot()
    registry.running["Other"] = SimpleNamespace(plugin_name="其它")

    assert registry.has_class("Demo")
    assert registry.plugin_class("Demo") is plugin_class
    assert registry.instance("Demo") is plugin_instance
    assert registry.plugin_ids() == ["Demo"]
    assert registry.running_ids() == ["Demo", "Other"]
    assert list(snapshot) == ["Demo"]


def test_registry_clear_preserves_compatibility_mapping_identity():
    """整体停止插件时原地清空，旧调用方持有的字典引用继续有效。"""
    registry = PluginRegistry()
    classes = registry.classes
    running = registry.running
    classes["Demo"] = object()
    running["Demo"] = object()

    registry.clear()

    assert registry.classes is classes
    assert registry.running is running
    assert classes == {}
    assert running == {}


def test_registry_tracks_runtime_status_generation_and_settling():
    """状态与后台收敛变化只在真实改变时推进刷新代次。"""
    registry = PluginRegistry()

    registry.set_runtime_status("Demo", PluginRuntimeStatus.READY)
    first_generation = registry.generation
    registry.set_runtime_status("Demo", PluginRuntimeStatus.READY)
    registry.set_settling(True)

    assert registry.runtime_status("Demo") is PluginRuntimeStatus.READY
    assert registry.runtime_status_snapshot() == {
        "Demo": PluginRuntimeStatus.READY,
    }
    assert registry.generation == first_generation + 1
    assert registry.settling is True

    registry.remove("Demo")

    assert registry.runtime_status("Demo") is None
