import pathlib,json,html,textwrap,subprocess
root=pathlib.Path(__file__).parent
for side in ['before','after']:
 events=[json.loads(x) for x in (root/(side+'.cast')).read_text().splitlines()[1:]]
 frames=root/(side+'-frames');frames.mkdir(exist_ok=True)
 content=''; manifest=[]
 def render(text,path):
  rows=[]
  for line in text.splitlines():rows.extend(textwrap.wrap(line,112,replace_whitespace=False,drop_whitespace=False) or [''])
  rows=rows[-40:]
  svg='<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="1040"><rect width="100%" height="100%" fill="#10151c"/>'
  svg+='<text x="24" y="32" fill="#90caf9" font-family="DejaVu Sans Mono" font-size="20">Recorded CLI output — '+side+' (paths anonymized)</text>'
  for i,row in enumerate(rows):svg+=f'<text x="24" y="{65+i*24}" fill="#e8edf2" font-family="DejaVu Sans Mono" font-size="19">{html.escape(row)}</text>'
  svg+='</svg>'
  p=path.with_suffix('.svg');p.write_text(svg);subprocess.run(['convert',str(p),str(path)],check=True,stdout=subprocess.DEVNULL,stderr=subprocess.PIPE)
 for i,event in enumerate(events):
  content+=event[2].replace('\r','')
  png=frames/(str(i)+'.png');render(content,png)
  duration=max(.1,(events[i+1][0]-event[0]) if i+1<len(events) else 5)
  manifest.extend([f"file '{png}'",f'duration {duration}'])
 (frames/'frames.txt').write_text('\n'.join(manifest)+f"\nfile '{png}'\n")
 subprocess.run(['ffmpeg','-y','-hide_banner','-loglevel','error','-f','concat','-safe','0','-i',str(frames/'frames.txt'),'-vf','fps=10','-c:v','libx264','-pix_fmt','yuv420p',str(root/(side+'.mp4'))],check=True)
 render(content,root/(side+'.png'))
