import os,json,pathlib,threading,time
os.umask(0o077)
os.environ['DATABASE_URL']='postgresql://u:p'+chr(64)+'localhost:1/db'
os.environ['REDIS_STREAMS_ENABLED']='false'
from app.multi_pipeline import _DecodedFrameObserver,_pipeline_message_callback
from app.source_adapters.rtsp import RtspSourceAdapter
from app.stream_lifecycle import RoleRunHandle
from pyservicemaker import Pipeline,Probe,Flow,RenderMode,BufferOperator
source=json.loads(pathlib.Path('/source.json').read_text())
events=[];counts={'tail':0};enough=threading.Event()
def on_update(*args):events.append(args)
handle=RoleRunHandle('det',1,on_update)
class Tail(BufferOperator):
    def handle_buffer(self,buffer):
        counts['tail']+=1
        if counts['tail']>=3:enough.set()
        return True
p=Pipeline('rtsp-isolation')
adapter=RtspSourceAdapter(source['uri'],source['options'],config_root='/tmp/source-config')
prepared=adapter.prepare('det',1)
observer=Probe('production-mux-probe',_DecodedFrameObserver(handle))
tail=Probe('tail-probe',Tail())
result={'input':'approved_rtsp','model_execution':False,'phase':'setup'}
def save():pathlib.Path('/evidence/rtsp.json').write_text(json.dumps(result,indent=2))
save()
try:
    capture=prepared.build_capture(Flow(p),p,decoded_probe=observer)
    capture.attach(tail).render(mode=RenderMode.DISCARD,sync=False,**{'async':False})
    handle.bind_pipeline(p)
    waiter=handle.start_pipeline(_pipeline_message_callback(handle,finite=False))
    result['phase']='started';save()
    enough.wait(30)
    result.update(tail=counts['tail'],mux=sum(e[2]=='source_stage' and e[3][0]=='decoded_frame_received' for e in events),
                  state_messages=sum(e[2]=='source_stage' and e[3][0]=='pipeline_state_changed' for e in events),phase='stopping')
    save()
    failure=handle.stop()
    waiter.wait()
    result.update(phase='stopped',stop_failure=failure.failure_stage if failure else None);save()
finally:prepared.cleanup()
