"""فحص دمج VDE في الوكيل — sync يبني كواشف edge_model/vlm ويتجاهل القواعد،
والتوزيع على motion يُطلق ONNX (حدث) وVLM (نداء سحابي)."""
import os
import sys

HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(HERE))          # edge/ ليُستورد vde
sys.path.insert(0, HERE)                            # لـ vde_runner

import vde_runner                                   # noqa: E402


class FakeOnnx:
    def __init__(self, path): pass
    def detect(self, jpeg, conf=0.35, iou=0.45):
        return [("fish", 0.9, (0, 0, 10, 10))] * 5


def test_runner():
    emitted, vlm_calls = [], []
    eng = vde_runner.build_engine(
        frame_fn=lambda cam: b"JPEG",
        vlm_fn=lambda key, frames, camera: (vlm_calls.append((key, camera, len(frames)))
                                            or {"flagged": False}),
        log_fn=lambda m: None, onnx_cls=FakeOnnx,
        emit_fn=lambda k, c, d: emitted.append((k, c, d.flagged)))

    features = [
        {"key": "fish_count", "kind": "edge_model",
         "config": {"camera": "cam1", "model": "m.onnx",
                    "detect_labels": ["fish"], "min_count": 3, "cooldown_s": 0}},
        {"key": "fight_detection", "kind": "vlm",
         "config": {"camera": "cam1", "frames": 4, "cooldown_s": 0}},
        {"key": "restricted_zone", "kind": "rule",       # يجب أن يتجاهله VDE
         "config": {"camera": "cam1", "coordinates": "0,0,1,1"}},
    ]
    n = vde_runner.sync(eng, features, "/models")
    assert n == 2, f"سجّل {n} بدل 2 (edge_model + vlm فقط)"
    assert ("restricted_zone", "cam1") not in eng.slots      # القاعدة تبقى للوكيل

    eng.dispatch_event("cam1", "motion")
    assert ("fish_count", "cam1", True) in emitted           # ONNX أطلق حدثاً
    assert vlm_calls and vlm_calls[0][0] == "fight_detection" and vlm_calls[0][1] == "cam1"
    assert vlm_calls[0][2] == 4                              # لقطات متتالية أُرسلت للسحابة
    # إعادة sync لا تُراكم
    assert vde_runner.sync(eng, features, "/models") == 2
    print("OK runner — sync يبني edge_model/vlm ويتجاهل القواعد؛ motion يُطلق ONNX+VLM")


if __name__ == "__main__":
    test_runner()
