#!/usr/bin/env bash
# diariz-yt — send a YouTube (or any yt-dlp-supported) link to Diariz for transcription + diarization.
#
#   diariz-yt <url> [--title "Custom title"] [--keep]
#
# Diariz has no URL ingest of its own (files only), so this fetches the audio and uploads it as a file:
#   1. yt-dlp pulls the best audio-only stream, natively (no transcode): YouTube's Opus/WebM, else M4A. Both are
#      formats Diariz accepts (its upload sniffs the bytes: wav/mp3/flac/ogg/webm, and m4a with UPLOAD_ALLOW_AAC).
#      Anything else is converted to Ogg/Opus with ffmpeg.
#   2. ffprobe reads the duration (Diariz wants durationMs).
#   3. POST /api/recordings (multipart, source=Upload) with the vaulted personal API token `diariz/api-token`. The
#      recording lands in Prime's personal room, and Diariz transcribes, diarizes and summarizes it on its own.
#
# Runs on nh3-dev: NH3's egress is residential, which YouTube does not bot-flag the way it flags colo IPs. Set
# DIARIZ_YT_PROXY (e.g. socks5h://100.64.0.1:1080, the nh3-scale residential proxy) to route yt-dlp through a proxy
# from anywhere else. Provenance is kept in the title: "<title> — <channel> [YouTube <id>]".
set -euo pipefail

BASE=${DIARIZ_URL:-https://diariz.nh3.phasefinal.com}
usage() { sed -n '2,4p' "$0" | sed 's/^# \{0,1\}//'; exit 2; }
url="" title="" keep=0
while [ $# -gt 0 ]; do
  case $1 in
    --title) title=${2:?--title needs a value}; shift 2 ;;
    --keep) keep=1; shift ;;
    -h|--help) usage ;;
    -*) echo "unknown option: $1" >&2; usage ;;
    *) [ -z "$url" ] || { echo "one URL at a time" >&2; exit 2; }; url=$1; shift ;;
  esac
done
[ -n "$url" ] || usage
for t in yt-dlp ffprobe ffmpeg curl python3 secret; do command -v "$t" >/dev/null || { echo "missing tool: $t" >&2; exit 3; }; done

work=$(mktemp -d "${TMPDIR:-/tmp}/diariz-yt.XXXXXX")
[ "$keep" = 1 ] || trap 'rm -rf "$work"' EXIT
proxy=(); [ -n "${DIARIZ_YT_PROXY:-}" ] && proxy=(--proxy "$DIARIZ_YT_PROXY")

echo "fetching audio: $url" >&2
yt-dlp "${proxy[@]}" --no-playlist --no-progress -q \
  -f 'bestaudio[ext=webm]/bestaudio[ext=m4a]/bestaudio' \
  -o "$work/%(id)s.%(ext)s" --write-info-json "$url"
info=$(ls "$work"/*.info.json 2>/dev/null | head -1); [ -n "$info" ] || { echo "yt-dlp wrote no metadata" >&2; exit 4; }
audio=$(ls "$work"/* | grep -v '\.info\.json$' | head -1); [ -s "$audio" ] || { echo "yt-dlp produced no audio" >&2; exit 4; }

case ${audio##*.} in
  webm|m4a|ogg|opus|mp3|wav|flac) ;;
  *) echo "converting ${audio##*.} to Ogg/Opus" >&2
     ffmpeg -hide_banner -loglevel error -i "$audio" -vn -c:a libopus -b:a 96k "$work/audio.ogg" && audio=$work/audio.ogg ;;
esac
# A bare .opus is Ogg inside; rename so the multipart filename matches what Diariz sniffs.
[ "${audio##*.}" = opus ] && { mv "$audio" "${audio%.opus}.ogg"; audio=${audio%.opus}.ogg; }

secs=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$audio")
dur_ms=$(python3 -c "import sys; print(int(float(sys.argv[1]) * 1000))" "$secs")
if [ -z "$title" ]; then
  title=$(python3 -c "
import json, sys
d = json.load(open(sys.argv[1]))
t = (d.get('title') or 'Untitled').strip(); ch = (d.get('channel') or d.get('uploader') or '').strip()
src = d.get('extractor_key') or 'web'; vid = d.get('id') or ''
print((t + (' — ' + ch if ch else '') + f' [{src} {vid}]')[:250])" "$info")
fi
bytes=$(stat -c %s "$audio")
echo "uploading \"$title\" ($(python3 -c "print(round($secs/60, 1))") min, $((bytes / 1024 / 1024)) MiB)" >&2

token=$(secret get diariz/api-token)
resp=$(curl -sS --fail-with-body -m 900 -X POST "$BASE/api/recordings" \
  -H @<(printf 'Authorization: Bearer %s\n' "$token") \
  -F "title=$title" -F "durationMs=$dur_ms" -F "source=Upload" \
  -F "audio=@$audio;filename=$(basename "$audio")") || { echo "upload failed: $resp" >&2; exit 5; }
unset token
python3 -c "
import json, sys
r = json.loads(sys.argv[1]); print('queued recording', r.get('id'), 'status', r.get('status'))
print('open:', sys.argv[2])" "$resp" "$BASE"
