#!/usr/bin/env bash
set -euo pipefail

WHISPER_DIR="${WHISPER_DIR:-$HOME/repos/whisper.cpp}"
WHISPER_MODEL="${WHISPER_MODEL:-$WHISPER_DIR/models/ggml-large-v3.bin}"
WHISPER_BIN="${WHISPER_BIN:-$WHISPER_DIR/build/bin/whisper-cli}"
VAD_MODEL="${VAD_MODEL:-$WHISPER_DIR/models/ggml-silero-v6.2.0.bin}"
TRANSLATE="${TRANSLATE:-1}"
SRC_LANG="${SRC_LANG:-auto}"
FORCE="${FORCE:-0}"
USE_VAD="${USE_VAD:-1}"
OUTPUT=""

usage() {
    cat <<EOF
Usage: video2srt [options] <video> [<video>...]

Generates an English .srt next to each video using whisper.cpp.

Options:
  -t, --transcribe   Transcribe in source language (default: translate to English)
  -l, --lang CODE    Force source language (default: auto-detect)
  -m, --model PATH   Path to ggml model (default: $WHISPER_MODEL)
  -o, --output PATH  Output .srt path (single input only; default: <video>.srt)
  -f, --force        Overwrite existing .srt
      --no-vad       Disable Silero VAD pre-filtering (VAD reduces hallucination loops)
  -h, --help         Show this help

Env overrides: WHISPER_DIR, WHISPER_MODEL, WHISPER_BIN
EOF
}

args=()
while [[ $# -gt 0 ]]; do
    case "$1" in
        -t|--transcribe) TRANSLATE=0; shift ;;
        -l|--lang) SRC_LANG="$2"; shift 2 ;;
        -m|--model) WHISPER_MODEL="$2"; shift 2 ;;
        -o|--output) OUTPUT="$2"; shift 2 ;;
        -f|--force) FORCE=1; shift ;;
        --no-vad) USE_VAD=0; shift ;;
        -h|--help) usage; exit 0 ;;
        --) shift; args+=("$@"); break ;;
        -*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
        *) args+=("$1"); shift ;;
    esac
done

if [[ ${#args[@]} -eq 0 ]]; then
    usage >&2; exit 2
fi

if [[ -n "$OUTPUT" && ${#args[@]} -gt 1 ]]; then
    echo "--output cannot be combined with multiple input files" >&2; exit 2
fi

[[ -x "$WHISPER_BIN" ]] || { echo "whisper-cli not found at $WHISPER_BIN" >&2; exit 1; }
[[ -f "$WHISPER_MODEL" ]] || { echo "model not found at $WHISPER_MODEL" >&2; exit 1; }
command -v ffmpeg >/dev/null || { echo "ffmpeg not installed" >&2; exit 1; }

for video in "${args[@]}"; do
    if [[ ! -f "$video" ]]; then
        echo "skip: $video (not a file)" >&2
        continue
    fi

    if [[ -n "$OUTPUT" ]]; then
        out_stem="${OUTPUT%.srt}"
        out_dir=$(dirname -- "$out_stem")
    else
        out_dir=$(dirname -- "$video")
        base=$(basename -- "$video")
        out_stem="$out_dir/${base%.*}"
    fi
    srt="$out_stem.srt"

    if [[ -f "$srt" && "$FORCE" != "1" ]]; then
        echo "skip: $srt exists (use --force to overwrite)"
        continue
    fi

    echo ">> $video"
    tmpwav=$(mktemp --suffix=.wav)
    trap 'rm -f "$tmpwav"' EXIT

    ffmpeg -hide_banner -loglevel error -y \
        -i "$video" -vn -ar 16000 -ac 1 -c:a pcm_s16le "$tmpwav"

    mkdir -p -- "$out_dir"
    whisper_args=(
        -m "$WHISPER_MODEL"
        -f "$tmpwav"
        -of "$out_stem"
        --output-srt
        -l "$SRC_LANG"
        -mc 0
    )
    [[ "$TRANSLATE" == "1" ]] && whisper_args+=(--translate)
    if [[ "$USE_VAD" == "1" ]]; then
        if [[ -f "$VAD_MODEL" ]]; then
            whisper_args+=(--vad --vad-model "$VAD_MODEL")
        else
            echo "warn: VAD model not found at $VAD_MODEL, running without VAD" >&2
            echo "      download with: sh $WHISPER_DIR/models/download-vad-model.sh silero-v6.2.0" >&2
        fi
    fi

    "$WHISPER_BIN" "${whisper_args[@]}"

    rm -f "$tmpwav"
    trap - EXIT
    echo "<< $srt"
done
