#!/usr/bin/env python3
"""Render the captured PTY output as readable terminal transcripts and a replay video."""
from pathlib import Path
import json, re, textwrap, html, subprocess, time, hashlib
root=Path(__file__).parent
for side,sha in [('before','c90b67859a6d85fc957f9ffe25ba95113c6479d3'),('after','e62cf38b2269921a25e485f12eaa3d765bb38585')]:
    run=next(root.glob(side+'-*'))
    events=[json.loads(x) for x in (run/'terminal.cast').read_text().splitlines()[1:]]
    def render(content,path):
        content=re.sub(r'\x1b\[[0-?]*[ -/]*[@-~]','',content).replace('\r','')
        lines=[]
        for line in content.splitlines(): lines.extend(textwrap.wrap(line,116,replace_whitespace=False,drop_whitespace=False) or [''])
        title=f'{side.upper()} | {sha[:10]} | Linux x86_64 | Codex CLI 0.167.1'
        svg=['<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600"><rect width="1600" height="1600" fill="#111827"/>',f'<text x="32" y="40" fill="#93c5fd" font-size="22" font-family="DejaVu Sans Mono">{html.escape(title)}</text>', '<text x="32" y="72" fill="#9ca3af" font-size="17" font-family="DejaVu Sans Mono">Real PTY output replay | 120 columns | scratch paths redacted to /evidence/run</text>']
        for i,line in enumerate(lines):
            color='#86efac' if line.startswith('$ ') else '#e5e7eb'
            svg.append(f'<text x="32" y="{112+i*23}" fill="{color}" font-size="19" font-family="DejaVu Sans Mono">{html.escape(line)}</text>')
        svg.append('</svg>')
        subprocess.run(['rsvg-convert','-o',str(path)],input=''.join(svg).encode(),check=True)
    render((run/'terminal.txt').read_text(),root/(side+'.png'))
    a=hashlib.sha256((root/(side+'.png')).read_bytes()).hexdigest(); time.sleep(.5)
    render((run/'terminal.txt').read_text(),root/(side+'.png'))
    assert a==hashlib.sha256((root/(side+'.png')).read_bytes()).hexdigest()
    # Replay the two actual command outputs in their recorded order, preserving output events.
    frames=run/'frames'; frames.mkdir()
    body=''; segments=[]
    for i,event in enumerate(events):
        body+=event[2]
        frame=frames/f'{i:03}.png'; render(body,frame)
        duration=max(.2,events[i+1][0]-event[0]) if i+1<len(events) else 5
        segments.append(f"file '{frame}'\nduration {duration:.6f}\n")
    concat=run/'frames.txt'; concat.write_text(''.join(segments)+f"file '{frame}'\n")
    subprocess.run(['ffmpeg','-y','-loglevel','error','-f','concat','-safe','0','-i',str(concat),'-vf','fps=10','-c:v','libx264','-pix_fmt','yuv420p',str(root/(side+'.mp4'))],check=True)
