#!/usr/bin/env bash
#
# build-presentation-hls.sh — Encode the Wasoria presentation video into ABR HLS
#
# For each locale (fr, en) it produces, from the 1080p master:
#   public/videos/presentation/<locale>/hls/master.m3u8      ← ABR master playlist
#   public/videos/presentation/<locale>/hls/1080p/index.m3u8 + segment_XXX.ts
#   public/videos/presentation/<locale>/hls/720p/index.m3u8  + segment_XXX.ts
#   public/images/home/presentation-poster-<locale>.webp     ← <video poster>
#   public/images/home/presentation-poster-<locale>.jpg      ← OG / JSON-LD thumbnail
#
# Both renditions are produced in a SINGLE ffmpeg pass with a fixed GOP, so the
# segment boundaries are identical across renditions — a hard requirement for
# glitch-free ABR switching.
#
# Usage:
#   ./scripts/build-presentation-hls.sh                 All locales
#   ./scripts/build-presentation-hls.sh fr              Single locale
#   ./scripts/build-presentation-hls.sh --posters-only  Re-cut posters, skip encoding
#   POSTER_AT=54 ./scripts/build-presentation-hls.sh    Override poster timestamp
#
# Requirements: ffmpeg with libx264, aac and libwebp.

set -euo pipefail

# ─── Configuration ───────────────────────────────────────────────────────────
POSTERS_ONLY=false
LOCALES=()

for arg in "$@"; do
    case "$arg" in
        --posters-only) POSTERS_ONLY=true ;;
        -*)
            echo "Unknown option: ${arg}" >&2
            exit 1
            ;;
        *) LOCALES+=("$arg") ;;
    esac
done

if [[ ${#LOCALES[@]} -eq 0 ]]; then
    LOCALES=(fr en)
fi

VIDEO_ROOT="public/videos/presentation"
POSTER_DIR="public/images/home"

# Poster frame timestamp (seconds). 0 = the video's own first frame, so the
# poster and the first painted frame are the same image: with in-view autoplay
# there is no visible jump when playback starts.
POSTER_AT="${POSTER_AT:-0}"

# HLS segment duration. 6s is the Apple-recommended VOD default: few enough
# requests for shared hosting, short enough for responsive ABR switching.
HLS_TIME=6

# GOP length in frames. Sources are 25 fps → 50 frames = 2s keyframe interval,
# an exact divisor of HLS_TIME so every segment starts on a keyframe.
GOP=50

# ─── Colors ──────────────────────────────────────────────────────────────────
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BLUE='\033[0;34m'; NC='\033[0m'
info()    { echo -e "${BLUE}[INFO]${NC}  $1"; }
success() { echo -e "${GREEN}[OK]${NC}    $1"; }
warn()    { echo -e "${YELLOW}[WARN]${NC}  $1"; }
error()   { echo -e "${RED}[ERROR]${NC} $1"; }

# ─── Pre-checks ──────────────────────────────────────────────────────────────
if [[ ! -f "artisan" ]]; then
    error "Run this script from the Laravel project root (artisan not found)."
    exit 1
fi

if ! command -v ffmpeg >/dev/null 2>&1; then
    error "ffmpeg not found in PATH."
    exit 1
fi

mkdir -p "${POSTER_DIR}"

# ─── Encode ──────────────────────────────────────────────────────────────────
for locale in "${LOCALES[@]}"; do
    SRC="${VIDEO_ROOT}/${locale}/presentation-wasoria-1080p-${locale}.mp4"
    OUT="${VIDEO_ROOT}/${locale}/hls"

    if [[ ! -f "${SRC}" ]]; then
        warn "Skipping '${locale}' — master not found: ${SRC}"
        continue
    fi

    if [[ "${POSTERS_ONLY}" == true ]]; then
        info "Skipping HLS encode for '${locale}' (--posters-only)"
    else

    info "Encoding ABR HLS for '${locale}' from ${SRC}"

    # ffmpeg does not create the %v sub-directories itself. Variant 0 is 720p
    # and variant 1 is 1080p: the master playlist lists variants in map order,
    # so putting the cheaper rendition first keeps the very first fragment small
    # for players that ignore BANDWIDTH.
    rm -rf "${OUT}"
    mkdir -p "${OUT}/0" "${OUT}/1"

    ffmpeg -hide_banner -loglevel warning -stats -y -i "${SRC}" \
        -filter_complex "[0:v]split=2[v0][v1];[v0]scale=w=1280:h=720[v0out];[v1]scale=w=1920:h=1080[v1out]" \
        -map "[v0out]" -map 0:a:0 \
        -map "[v1out]" -map 0:a:0 \
        -preset slow -pix_fmt yuv420p \
        -g "${GOP}" -keyint_min "${GOP}" -sc_threshold 0 \
        -c:v:0 libx264 -profile:v:0 main -level:v:0 3.1 \
        -b:v:0 2800k -maxrate:v:0 2996k -bufsize:v:0 4200k \
        -c:v:1 libx264 -profile:v:1 high -level:v:1 4.0 \
        -b:v:1 5000k -maxrate:v:1 5350k -bufsize:v:1 7500k \
        -c:a aac -b:a 128k -ac 2 -ar 48000 \
        -f hls \
        -hls_time "${HLS_TIME}" \
        -hls_playlist_type vod \
        -hls_segment_type mpegts \
        -hls_flags independent_segments \
        -hls_list_size 0 \
        -hls_segment_filename "${OUT}/%v/segment_%03d.ts" \
        -master_pl_name "master.m3u8" \
        -var_stream_map "v:0,a:0 v:1,a:1" \
        "${OUT}/%v/index.m3u8"

    # ffmpeg 4.4 has no `name=` key in -var_stream_map, so it can only emit the
    # numeric variant directories above. Rename them to readable resolutions and
    # repoint the master playlist.
    mv "${OUT}/0" "${OUT}/720p"
    mv "${OUT}/1" "${OUT}/1080p"
    sed -i -e 's#^0/index\.m3u8$#720p/index.m3u8#' -e 's#^1/index\.m3u8$#1080p/index.m3u8#' "${OUT}/master.m3u8"

    success "HLS written to ${OUT} ($(du -sh "${OUT}" | cut -f1), $(find "${OUT}" -name '*.ts' | wc -l) segments)"

    fi

    # ─── Poster frames ───────────────────────────────────────────────────────
    # The two outputs are tuned for different audiences on purpose.
    #
    # WebP → the <video poster> a visitor downloads. The player is at most
    # ~1250 CSS px wide, and the poster is on screen for barely a second before
    # autoplay replaces it, so 1600px @ q72 is the right weight/sharpness
    # trade-off (~175 KB). The opening aerial shot is full of vegetation and
    # gravel detail and compresses far worse than a darker frame would.
    #
    # JPEG → the JSON-LD / OG thumbnail, fetched by crawlers and social
    # scrapers, never by a visitor. It costs page weight nothing, so keep it at
    # full 1920px quality where Google prefers it.
    info "Extracting poster for '${locale}' at ${POSTER_AT}s"

    ffmpeg -hide_banner -loglevel error -y -ss "${POSTER_AT}" -i "${SRC}" \
        -frames:v 1 -vf "scale=1600:-2" -c:v libwebp -quality 72 -compression_level 6 \
        "${POSTER_DIR}/presentation-poster-${locale}.webp"

    ffmpeg -hide_banner -loglevel error -y -ss "${POSTER_AT}" -i "${SRC}" \
        -frames:v 1 -vf "scale=1920:-2" -q:v 4 \
        "${POSTER_DIR}/presentation-poster-${locale}.jpg"

    success "Posters: ${POSTER_DIR}/presentation-poster-${locale}.{webp,jpg} ($(du -h "${POSTER_DIR}/presentation-poster-${locale}.webp" | cut -f1) / $(du -h "${POSTER_DIR}/presentation-poster-${locale}.jpg" | cut -f1))"
done

echo ""
success "Done. Remember to run ./deploy.sh so the new segments reach the server."
