"""SDK public metadata copy/release, without model/RTSP or external endpoints."""
import ctypes
import gc
import sys
import time
import traceback
import gi
gi.require_version('Gst','1.0')
from gi.repository import Gst
from pyservicemaker import Buffer
from app.frame_ingress import FrameIngress
from app.byte_tracking import ByteTracker
from app.det_result_path import DetResultPath
from app.multi_pipeline import _DecodedFrameObserver,_make_retriever,ResultCollector
from app.stream_lifecycle import RoleRunHandle
from app.pose_config import PoseConfig

Gst.init(None)
fixture=ctypes.CDLL(sys.argv[1])
fixture.attach_pose_fixture.argtypes=[ctypes.c_size_t,ctypes.c_bool,ctypes.c_uint]
fixture.copy_fixture_frames.argtypes=[ctypes.c_size_t,ctypes.c_size_t]
class DiagnosedIngress(FrameIngress):
    def stamp(self,batch):
        try:
            return super().stamp(batch)
        except Exception:
            # Probe stdout/stderr must be redirected to the private bounded task log.
            traceback.print_exc()
            raise

ingress=DiagnosedIngress('test','camera','stream','run',1)
collector=ResultCollector(['pose'])
errors=[]
path=DetResultPath(ingress,ByteTracker(),'RFDETRKeypointPreview',.5,collector,
                   lambda:True,lambda:errors.append(True),pose_config=PoseConfig(enabled=True))
handle=RoleRunHandle('pose',1)
observer=_DecodedFrameObserver(handle,ingress=ingress)
receiver=_make_retriever('pose','unused','unused',collector,0,{'n':0},component_id=7,result_path=path)()
path.start()
try:
    for seq,populated in enumerate((True,False)):
        source=Gst.Buffer.new()
        assert fixture.attach_pose_fixture(hash(source),populated,seq)==0
        wrapped=Buffer(source)
        assert observer.handle_buffer(wrapped), dict(sequence=seq,
            failure=handle.failure.as_dict() if handle.failure else None,
            performance=ingress.metrics.snapshot())
        target=Gst.Buffer.new()
        assert fixture.copy_fixture_frames(hash(source),hash(target))==0
        del source,wrapped
        gc.collect()
        copied=Buffer(target)
        for fm in copied.batch_meta.frame_items:
            other=FrameIngress('test','camera','stream','other',2)
            try:other.copy(fm)
            except ValueError:pass
            else:raise AssertionError('stale Frame accepted')
        assert receiver.consume(copied)==1
        del copied,target
        gc.collect()
        end=time.monotonic()+3
        while path.status().get('processed',0)<=seq and not errors and time.monotonic()<end:time.sleep(.01)
        assert not errors and path.status()['processed']==seq+1
        result=path.latest_result()
        assert result.frame.frame_seq==seq
        assert len(result.commands)==int(populated)
        if populated:
            assert result.commands[0].track_id is not None
            assert len(result.snapshot()['objects'][0]['keypoints'])==17
finally:path.close(3)
assert not path._thread.is_alive() and path.latest_result() is None
print('SDK_POSE_COPY_RELEASE_TRACKING_SNAPSHOT_PASS')
