import pathlib,json,textwrap,sys,subprocess
from PIL import Image,ImageDraw,ImageFont
p=pathlib.Path(sys.argv[1]); font=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf',20)
def compact(lines):
 out=[]; migrations=False
 for line in lines:
  if 'INFO (#1): Migrations ran successfully' in line: migrations=True; out.append('[migration list omitted here; complete output in transcript]'); continue
  if migrations:
   if line=='}': migrations=False
   continue
  if 'Migrations applied:' in line: line='  Migrations applied: 55_OrchestrationV2 through 80_ScheduledTaskThreadMode'
  if line.startswith('    at '): continue
  out.extend(textwrap.wrap(line,128,replace_whitespace=False,drop_whitespace=False) or [''])
 return out
def render(lines,target,tail=False):
 lines=compact(lines)
 if tail: lines=lines[-44:]
 im=Image.new('RGB',(1600,1200),'#11151c'); d=ImageDraw.Draw(im)
 d.text((24,15),'REAL COMMAND OUTPUT — synthetic database reproduction',font=font,fill='#91baff')
 for i,line in enumerate(lines):
  color='#e6e8ee'
  if 'EXIT STATUS' in line or 'unchanged:' in line or 'DESTINATION:' in line: color='#ffd38a'
  d.text((24,55+i*25),line,font=font,fill=color)
 im.save(target)
for side in ['before','after']:
 lines=(p/(side+'.txt')).read_text().splitlines(); split=next(i for i,l in enumerate(lines) if l.startswith('SOURCE: schema-migrated'))
 render(lines[:split],p/(side+'-pre-v2.png'))
 render(lines[:3]+['']+lines[split:],p/(side+'-schema-migrated.png'))
 records=json.loads((p/(side+'-frames.json')).read_text()); frames=p/(side+'-frames'); frames.mkdir()
 start=records[0][0]; duration=records[-1][0]-start+4
 # The movie replays the captured output at its original timestamps, then holds the final view.
 for n in range(int(duration*4)+1):
  upto=[r for r in records if r[0]<=start+n/4]; current=upto[-1][1] if upto else []
  render(current,frames/(f'{n:04}.png'),True)
 subprocess.run(['ffmpeg','-v','error','-y','-framerate','4','-i',str(frames/'%04d.png'),'-c:v','libx264','-pix_fmt','yuv420p',str(p/(side+'.mp4'))],check=True)
