#!/usr/bin/env bash
# scripts/manual/run_upstream_av_sync.sh
#
# Manual: capture the real Tethys webcam/mic endpoints while the shared-clock
# sync probe streams upstream media through Lesavka, then analyze the skew.

set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../.." >/dev/null 2>&1 && pwd)"

TETHYS_HOST=${TETHYS_HOST:-tethys}
LESAVKA_SERVER_ADDR=${LESAVKA_SERVER_ADDR:-http://38.28.125.112:50051}
PROBE_DURATION_SECONDS=${PROBE_DURATION_SECONDS:-10}
PROBE_WARMUP_SECONDS=${PROBE_WARMUP_SECONDS:-4}
LEAD_IN_SECONDS=${LEAD_IN_SECONDS:-8}
TAIL_SECONDS=${TAIL_SECONDS:-2}
CAPTURE_SECONDS=${CAPTURE_SECONDS:-$((PROBE_DURATION_SECONDS + PROBE_WARMUP_SECONDS + LEAD_IN_SECONDS + TAIL_SECONDS))}
REMOTE_CAPTURE=${REMOTE_CAPTURE:-/tmp/lesavka-upstream-av-sync.mkv}
LOCAL_OUTPUT_DIR=${LOCAL_OUTPUT_DIR:-"${REPO_ROOT}/tmp"}
VIDEO_SIZE=${VIDEO_SIZE:-1280x720}
VIDEO_FPS=${VIDEO_FPS:-30}
VIDEO_FORMAT=${VIDEO_FORMAT:-mjpeg}
REMOTE_AUDIO_SOURCE=${REMOTE_AUDIO_SOURCE:-auto}
SSH_OPTS=${SSH_OPTS:-"-o BatchMode=yes -o ConnectTimeout=5"}
LOCAL_AUDIO_SANITY=${LOCAL_AUDIO_SANITY:-1}

mkdir -p "${LOCAL_OUTPUT_DIR}"
STAMP="$(date +%Y%m%d-%H%M%S)"
LOCAL_CAPTURE="${LOCAL_OUTPUT_DIR}/lesavka-upstream-av-sync-${STAMP}.mkv"

if [[ "${LOCAL_AUDIO_SANITY}" != "0" ]]; then
  echo "==> verifying local speaker-to-mic sanity before upstream sync run"
  "${SCRIPT_DIR}/run_local_audio_sanity.sh"
fi

echo "==> starting Tethys capture on ${TETHYS_HOST}"
ssh ${SSH_OPTS} "${TETHYS_HOST}" bash -s -- \
  "${REMOTE_CAPTURE}" \
  "${CAPTURE_SECONDS}" \
  "${VIDEO_SIZE}" \
  "${VIDEO_FPS}" \
  "${VIDEO_FORMAT}" \
  "${REMOTE_AUDIO_SOURCE}" <<'REMOTE_CAPTURE_SCRIPT' &
set -euo pipefail
remote_capture=$1
capture_seconds=$2
video_size=$3
video_fps=$4
video_format=$5
remote_audio_source=$6

rm -f "${remote_capture}"
video_args=(-f video4linux2 -framerate "${video_fps}" -video_size "${video_size}")
if [[ -n "${video_format}" ]]; then
  video_args+=(-input_format "${video_format}")
fi

resolve_pulse_source() {
  if ! command -v pactl >/dev/null 2>&1; then
    return 1
  fi
  pactl list short sources 2>/dev/null \
    | awk '
      /alsa_input\..*Lesavka_Composite/ { print $2; found=1; exit }
      /Lesavka_Composite/ && !fallback { fallback=$2 }
      END {
        if (found) exit 0
        if (fallback != "") { print fallback; exit 0 }
        exit 1
      }
    '
}

audio_mode="alsa"
alsa_audio_dev="hw:3,0"
pulse_source=""
if [[ "${remote_audio_source}" == "auto" ]]; then
  if pulse_source="$(resolve_pulse_source)"; then
    audio_mode="pulse"
  else
    printf 'PipeWire Lesavka source not found; falling back to hw:3,0\n' >&2
  fi
elif [[ "${remote_audio_source}" == pulse:* ]]; then
  audio_mode="pulse"
  pulse_source="${remote_audio_source#pulse:}"
elif [[ "${remote_audio_source}" == alsa:* ]]; then
  alsa_audio_dev="${remote_audio_source#alsa:}"
else
  printf 'unsupported REMOTE_AUDIO_SOURCE=%s\n' "${remote_audio_source}" >&2
  exit 64
fi

if [[ "${audio_mode}" == "pulse" ]]; then
  printf 'using Pulse source: %s\n' "${pulse_source}" >&2
  ffmpeg -hide_banner -loglevel error -y \
    -thread_queue_size 1024 \
    "${video_args[@]}" \
    -i /dev/video0 \
    -thread_queue_size 1024 \
    -f pulse \
    -i "${pulse_source}" \
    -t "${capture_seconds}" \
    -c:v ffv1 -level 3 -g 1 \
    -c:a pcm_s16le \
    "${remote_capture}"
else
  ffmpeg -hide_banner -loglevel error -y \
    -thread_queue_size 1024 \
    "${video_args[@]}" \
    -i /dev/video0 \
    -thread_queue_size 1024 \
    -f alsa -ac 2 -ar 48000 \
    -i "${alsa_audio_dev}" \
    -t "${capture_seconds}" \
    -c:v ffv1 -level 3 -g 1 \
    -c:a pcm_s16le \
    "${remote_capture}"
fi
REMOTE_CAPTURE_SCRIPT
capture_pid=$!

sleep "${LEAD_IN_SECONDS}"

echo "==> running local Lesavka sync probe against ${LESAVKA_SERVER_ADDR}"
probe_status=0
(
  cd "${REPO_ROOT}"
  cargo run -p lesavka_client --bin lesavka-sync-probe -- \
    --server "${LESAVKA_SERVER_ADDR}" \
    --duration-seconds "${PROBE_DURATION_SECONDS}" \
    --warmup-seconds "${PROBE_WARMUP_SECONDS}"
) || probe_status=$?

capture_status=0
wait "${capture_pid}" || capture_status=$?

if ssh ${SSH_OPTS} "${TETHYS_HOST}" "test -f '${REMOTE_CAPTURE}'"; then
  echo "==> fetching capture back to ${LOCAL_CAPTURE}"
  scp ${SSH_OPTS} "${TETHYS_HOST}:${REMOTE_CAPTURE}" "${LOCAL_CAPTURE}"
fi

if [[ "${probe_status}" -ne 0 ]]; then
  echo "sync probe failed with status ${probe_status}" >&2
  [[ -f "${LOCAL_CAPTURE}" ]] && echo "partial capture preserved at ${LOCAL_CAPTURE}" >&2
  exit "${probe_status}"
fi
if [[ "${capture_status}" -ne 0 ]]; then
  if [[ "${capture_status}" -eq 141 && -f "${LOCAL_CAPTURE}" ]]; then
    echo "Tethys capture ended with PipeWire SIGPIPE after ffmpeg closed; accepting preserved capture ${LOCAL_CAPTURE}" >&2
  else
  echo "Tethys capture failed with status ${capture_status}" >&2
  [[ -f "${LOCAL_CAPTURE}" ]] && echo "partial capture preserved at ${LOCAL_CAPTURE}" >&2
  exit "${capture_status}"
  fi
fi

echo "==> analyzing capture"
(
  cd "${REPO_ROOT}"
  cargo run -p lesavka_client --bin lesavka-sync-analyze -- "${LOCAL_CAPTURE}"
)

echo "==> done"
echo "capture: ${LOCAL_CAPTURE}"
