"""SDK CPU fixture probe: python tests/native_metadata_sdk_probe.py <fixture.so>."""
import ctypes
import gc
import sys
import tempfile
from pathlib import Path

import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from pyservicemaker import Buffer
from app.native_metadata import copy_detection_frame
from app.multi_pipeline import _make_retriever, ResultCollector
from app.medium_preprocess import medium_preprocess_config
from pyservicemaker.flow import Flow, StreamInfo

Gst.init(None)
lib = ctypes.CDLL(sys.argv[1])
lib.attach_fixture.argtypes = [ctypes.c_size_t, ctypes.c_bool, ctypes.c_bool]
lib.attach_fixture.restype = ctypes.c_int
lib.dimension_contract.restype = ctypes.c_int
assert lib.dimension_contract() == 0
for populated, copy_frame in ((True, False), (False, False), (True, True), (False, True)):
    raw = Gst.Buffer.new()
    # 실제 SDK FrameMeta 복사에서 production copy/release와 원본 해제를 통과한다.
    assert lib.attach_fixture(hash(raw), populated, copy_frame) == 0
    wrapped = Buffer(raw)
    copies = [copy_detection_frame(f, 7) for f in wrapped.batch_meta.frame_items]
    assert copies[0].frame_number == 0
    assert len(copies[0].detections) == int(populated)
    collector = ResultCollector(required_roles=['det'])
    receiver = _make_retriever('det', 'unused', 'unused', collector, 0, {'n': 0}, component_id=7)()
    receiver.consume(wrapped)
    assert collector.frames[0]['det']['count'] == int(populated)
    del wrapped, raw
    gc.collect()
    if populated:
        assert copies[0].detections[0].bbox_xyxy == (.1, .1, .3, .3)
print('SDK_NATIVE_BRIDGE_PASS: frame0, empty, SDK frame-meta copy/release, detached lifetime, consume; no GPU')

class RecordingPipeline:
    def __init__(self):
        self.properties = []
    def add(self, element, name, properties=None):
        if element == 'nvdspreprocess':
            self.properties.append(properties)
        return self
    def link(self, *args, **kwargs):
        return self

with tempfile.TemporaryDirectory() as directory:
    config = Path(directory) / 'preprocess.ini'
    config.write_text(medium_preprocess_config(7))
    default, explicit = RecordingPipeline(), RecordingPipeline()
    Flow(default, streams=[StreamInfo('input', media_type='video')]).preprocess(str(config))
    Flow(explicit, streams=[StreamInfo('input', media_type='video')]).preprocess(str(config), target_unique_ids=7)
    assert default.properties[0]['target-unique-ids'] == 1
    assert explicit.properties[0]['target-unique-ids'] == 7
print('SDK_PREPROCESS_TARGET_OVERRIDE_PASS: public Flow mapping, no Pipeline execution')
