"""Record a live command's stdout as a terminal-style MP4, plus raw transcript.
Usage: python3 record.py <package-cwd> <output-directory> <commit-label>
Requires Pillow, ffmpeg, and DejaVu Sans Mono. No output is invented.
"""
import sys, subprocess, time, selectors, textwrap
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
cwd, directory, label = sys.argv[1:]
out=Path(directory); out.mkdir(parents=True, exist_ok=True)
font=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf',18)
command=subprocess.Popen(['node','repro.ts',str(out),label],cwd=cwd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True,bufsize=1)
encoder=subprocess.Popen(['ffmpeg','-y','-loglevel','error','-f','rawvideo','-pixel_format','rgb24','-video_size','1440x810','-framerate','10','-i','-','-c:v','libx264','-pix_fmt','yuv420p',str(out/'recording.mp4')],stdin=subprocess.PIPE)
selector=selectors.DefaultSelector(); selector.register(command.stdout,selectors.EVENT_READ)
lines=[]; start=time.monotonic(); ended=None; frames=0
while True:
 for key,mask in selector.select(timeout=0):
  line=key.fileobj.readline()
  if line:
   lines.append(line.rstrip()); print(line,end='',flush=True)
  else: selector.unregister(key.fileobj)
 now=time.monotonic()
 if command.poll() is not None and not selector.get_map() and ended is None: ended=now
 if now-start >= frames/10:
  im=Image.new('RGB',(1440,810),'#10151c'); d=ImageDraw.Draw(im)
  d.text((28,22),'LIVE COMMAND OUTPUT RECORDING | T3 Code SSH timeout',font=font,fill='#ffffff')
  d.text((28,54),f'commit {label} | elapsed {now-start:.1f}s | 1440 x 810',font=font,fill='#a9b7ca')
  y=110
  for line in lines:
   for part in textwrap.wrap(line,124,replace_whitespace=False) or ['']:
    color='#ffb0aa' if 'liveProxy=true' in line else '#a9ecc0' if 'liveProxy=false' in line else '#d5dde9'
    d.text((28,y),part,font=font,fill=color); y+=27
  encoder.stdin.write(im.tobytes()); frames+=1
 if ended and now-ended>=3:
  im.save(out/'final.png'); break
 time.sleep(.01)
encoder.stdin.close(); encoder.wait()
(out/'transcript.txt').write_text('\n'.join(lines)+'\n')
sys.exit(command.returncode or encoder.returncode)
