#!/usr/bin/env bash
# Record a C12 prototype walkthrough, brand it, and export. Unattended.
#   ./record.sh ios      | ./record.sh android
set -e
# Run this from anywhere: it locates itself, and everything it needs is relative.
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
AUDIT="$(cd "$HERE/.." && pwd)"          # .../c12/audit
OUT="$HERE/out"                           # renders land here, git-ignored
mkdir -p "$OUT"
cd "$OUT"
PLAT="${1:-ios}"
RM="${RM_OPENSCREEN:-$HOME/Development/openscreen/rolemodel-openscreen}"
OS="/Applications/Openscreen.app/Contents/MacOS/Openscreen"
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
for bin in "$OS" "$CHROME"; do
  [ -x "$bin" ] || { echo "not found: $bin"; exit 1; }
done
[ -f "$RM/bin/rm-video.mjs" ] || { echo "rolemodel-openscreen not at $RM — set RM_OPENSCREEN"; exit 1; }
# A separate Electron profile: the dev build of OpenScreen holds the default one,
# and sharing it makes `sources` fail with "Failed to get sources".
PROFILE="--user-data-dir=$HOME/.openscreen-cli-profile"   # no spaces: an unquoted
                                                          # expansion word-splits otherwise

if [ "$PLAT" = "android" ]; then
  DIR="prototype-android"; TITLE="C12 Android — Interactive Prototype"
  PACE=5.42; SECS=${SECS_OVERRIDE:-272}; NAME="c12-android"; CARD="C12 on Android"
else
  DIR="prototype";         TITLE="C12 Native — Interactive Prototype"
  PACE=5.15; SECS=${SECS_OVERRIDE:-258}; NAME="c12-ios";     CARD="C12 — the native app"
fi
URL="file://$AUDIT/$DIR/index.html"

echo "▸ closing any existing prototype window"
osascript -e "tell application \"Google Chrome\"
  repeat with w from (count of windows) to 1 by -1
    try
      if title of active tab of window w is \"$TITLE\" then close window w
    end try
  end repeat
end tell" >/dev/null 2>&1 || true
sleep 2

# 16:9 and chrome-less, and film=1 so the capture is the device and its caption —
# the scene rail and transport are navigation for a person at a desk and read as
# developer chrome on video.
echo "▸ opening a clean 1600x900 window"
"$CHROME" --app="$URL?film=1&scene=${PLAT:0:1}01" --window-size=1600,900 --window-position=40,60 >/dev/null 2>&1 &
sleep 7

# Park the pointer off the recorded window. The overlay cursor follows the real
# mouse, and marking the samples invisible did not stop it being drawn — moving it
# out of frame is the reliable fix. Nothing here is clicked by hand anyway.
cliclick m:3300,1900 >/dev/null 2>&1 || echo "  (cliclick missing — the pointer may appear)"

echo "▸ recording ${SECS}s of \"$TITLE\""
"$OS" $PROFILE record --window "${TITLE%% —*}" --duration "$SECS" \
  --cursor editable-overlay --project "$NAME.openscreen" --json > "record-$PLAT.log" 2>&1 &
REC=$!
sleep 10
grep -q "Recording started" "record-$PLAT.log" || { echo "recorder did not start"; tail -3 "record-$PLAT.log"; exit 1; }

# Navigating restarts the page, so autoplay fires inside the recording.
# A keystroke is not reliable here — it lands on whichever window is frontmost.
echo "▸ starting the walkthrough"
osascript -e "tell application \"Google Chrome\"
  repeat with w from 1 to (count of windows)
    try
      if title of active tab of window w is \"$TITLE\" then
        set URL of active tab of window w to \"$URL?film=1&autoplay=1&pace=$PACE\"
      end if
    end try
  end repeat
end tell" >/dev/null 2>&1
wait $REC
echo "▸ recorded"

# The overlay cursor is drawn from a sidecar beside the capture, found by convention
# as <video>.cursor.json. Setting every sample to visible:false did not stop it, so
# empty the sample list instead — the file stays valid, there is just nothing to draw.
node -e "
const fs=require('fs');
const d=JSON.parse(fs.readFileSync('$NAME.openscreen'));
const side=d.media.screenVideoPath+'.cursor.json';
if(fs.existsSync(side)){
  const c=JSON.parse(fs.readFileSync(side));
  const n=(c.samples||[]).length;
  c.samples=[];
  fs.writeFileSync(side,JSON.stringify(c));
  console.log('  cursor removed — '+n+' samples dropped');
}"

echo "▸ branding"
node "$RM/bin/rm-video.mjs" brand "$NAME.openscreen" --preset rolemodel --variant master \
  --title "$CARD" --eyebrow "UX Assessment" --watermark --duration-ms "$((SECS*1000))" | tail -2

# Auto-zoom crops the captions off the left edge; padding sits the capture on the
# wallpaper rather than letterboxing to black.
node -e "
const fs=require('fs');const f='$NAME.openscreen';const d=JSON.parse(fs.readFileSync(f));
// editable-overlay keeps the cursor out of the captured pixels; flipping the mode
// here stops the exporter drawing it back in. Net effect: no cursor at all.
d.media.cursorCaptureMode = 'system';
Object.assign(d.editor,{
  padding:0.05, shadowIntensity:0.28, borderRadius:22,
  // Auto-zoom read the cursor telemetry and cropped the caption off the left edge.
  autoZoomEnabled:false, zoomRegions:[],
  // Chrome's --app window still carries a slim title bar on macOS. 32px of a
  // 900px window is 3.6%; trimming it is cheaper than fighting Chrome for it.
  cropRegion:{x:0, y:0.036, width:1, height:0.964}
});
// The watermark ships bottom-right at x:74, which is exactly where the device is.
for (const a of (d.editor.annotationRegions||[])) {
  if (typeof a?.content === 'string' && a.content.includes('RoleModel')) {
    a.position = { x: 2, y: 91 };
    if (a.style) a.style.textAlign = 'left';
  }
}
fs.writeFileSync(f,JSON.stringify(d,null,2));"

echo "▸ exporting"
"$OS" $PROFILE export "$NAME.openscreen" -o "$NAME-master.mp4" --json > "export-$PLAT.log" 2>&1
ffmpeg -v error -i "$NAME-master.mp4" -vf scale=1920:-2 -c:v libx264 -preset medium -crf 23 \
  -pix_fmt yuv420p -movflags +faststart -y "$NAME-1080p.mp4"
echo "▸ done"
ls -lh "$NAME-master.mp4" "$NAME-1080p.mp4"
echo
echo "  in  $OUT"
echo "  share  $NAME-1080p.mp4"
