#!/bin/bash

# Robust run script for 24/7 YouTube live radio
# - wait for STREAM_KEY instead of exiting immediately (useful on Spaces)
# - resample audio to 48kHz to avoid encoder reconfiguration
# - log ffmpeg stderr to /tmp/ffmpeg.log and forward to container stderr
# - attempt primary then backup ingest on quick failures
# - exponential backoff on repeated failures

set -o errexit
set -o nounset
set +o pipefail || true

# Configuration
TRACKS_DIR="./tracks"
QUEUE_FILE="./queue.txt"
BACKGROUND_VIDEO="./background.mp4"

# Timing / resiliency
RECONNECT_WAIT=12       # seconds to wait before connecting so YouTube can teardown
QUICK_FAIL_SECS=20      # if ffmpeg exits faster than this, treat as quick failure and try backup
retry_delay=1

LOG_FILE="/tmp/ffmpeg.log"

# Validate required files (do not check STREAM_KEY here; wait for it below)
if [ ! -d "$TRACKS_DIR" ]; then
    echo "CRITICAL ERROR: $TRACKS_DIR directory not found!"
    exit 1
fi

if [ ! -f "$BACKGROUND_VIDEO" ]; then
    echo "CRITICAL ERROR: $BACKGROUND_VIDEO file not found!"
    exit 1
fi

# Wait for STREAM_KEY to be set (Spaces-friendly). When set in Settings, redeploy or restart the Space.
if [ -z "${STREAM_KEY:-}" ]; then
    echo "WARNING: STREAM_KEY not set. The script will wait until STREAM_KEY is provided in the environment."
    while [ -z "${STREAM_KEY:-}" ]; do
        echo "Waiting for STREAM_KEY... (set this in Spaces Settings -> Environment variables)"
        sleep 10
    done
fi

RTMP_URL_PRIMARY="rtmp://a.rtmp.youtube.com/live2/${STREAM_KEY}"
RTMP_URL_BACKUP="rtmp://b.rtmp.youtube.com/live2/${STREAM_KEY}"

# Function to compile a shuffled queue of your tracks with proper formatting
generate_queue() {
    : > "$QUEUE_FILE"

    find "$TRACKS_DIR" -type f \( -iname "*.mp3" -o -iname "*.wav" -o -iname "*.flac" \) | shuf | while read -r file; do
        echo "file '$file'" >> "$QUEUE_FILE"
    done

    if [ ! -s "$QUEUE_FILE" ]; then
        echo "CRITICAL ERROR: No playable audio tracks found in $TRACKS_DIR!"
        return 1
    fi

    return 0
}

# Attempt to run ffmpeg to the given RTMP URL. Sets LAST_RUNTIME and LAST_RC globals.
attempt_stream() {
    local url="$1"

    # rotate log
    if [ -f "$LOG_FILE" ]; then
        mv "$LOG_FILE" "${LOG_FILE}.prev" || true
    fi

    echo "Starting ffmpeg -> $url"
    local start_ts
    start_ts=$(date +%s)

    # Run ffmpeg and tee stderr both to the log file and to stderr so Spaces shows ffmpeg output in the container logs
    ffmpeg -hide_banner -loglevel info -re \
        -stream_loop -1 -i "$BACKGROUND_VIDEO" \
        -f concat -safe 0 -i "$QUEUE_FILE" \
        -map 0:v -map 1:a \
        -c:v libx264 -vf "scale=-2:720,format=yuv420p" -r 24 -g 48 -preset ultrafast -b:v 1500k -maxrate 1500k -bufsize 3000k \
        -c:a aac -b:a 128k -ar 48000 -ac 2 -af "aresample=48000" \
        -shortest -f flv "$url" 2> >(tee -a "$LOG_FILE" >&2) || true

    LAST_RC=$?
    local end_ts
    end_ts=$(date +%s)
    LAST_RUNTIME=$((end_ts - start_ts))

    echo "ffmpeg exit code=$LAST_RC run_time=${LAST_RUNTIME}s" >> "$LOG_FILE" || true

    return $LAST_RC
}

# --- Lightweight health-check server to satisfy platform probes ---
echo "Starting lightweight Python health-check server on port 7860..."
python3 -m http.server 7860 > /dev/null 2>&1 &
# -------------------------------

# Main loop: generate queue, then attempt primary -> possibly backup, with backoff
while true; do
    echo "Generating fresh audio rotation queue..."
    if ! generate_queue; then
        echo "No tracks found; retrying in 30s..."
        sleep 30
        continue
    fi

    echo "Waiting ${RECONNECT_WAIT}s before connecting (allow previous sessions to close)..."
    sleep "$RECONNECT_WAIT"

    echo "Trying primary ingest: $RTMP_URL_PRIMARY"
    attempt_stream "$RTMP_URL_PRIMARY"
    rc=$?

    # if return code is zero, ffmpeg exited cleanly (we'll loop)
    if [ $rc -eq 0 ]; then
        echo "ffmpeg exited normally (code 0). Restarting loop..."
        retry_delay=1
        continue
    fi

    echo "Primary ingest failed with code $rc after ${LAST_RUNTIME}s. See $LOG_FILE"

    # If it failed quickly, try backup once
    if [ "$LAST_RUNTIME" -lt "$QUICK_FAIL_SECS" ]; then
        echo "Primary failed quickly (<${QUICK_FAIL_SECS}s) — attempting backup ingest: $RTMP_URL_BACKUP"
        attempt_stream "$RTMP_URL_BACKUP"
        rc2=$?
        if [ $rc2 -eq 0 ]; then
            echo "Backup run exited normally (code 0). Restarting loop..."
            retry_delay=1
            continue
        fi
        echo "Backup ingest also failed with code $rc2 after ${LAST_RUNTIME}s. See $LOG_FILE"
    fi

    # exponential backoff to avoid hammering in case of repeated failures
    echo "Sleeping for ${retry_delay}s before retrying..."
    sleep $retry_delay
    retry_delay=$(( retry_delay * 2 ))
    [ $retry_delay -gt 300 ] && retry_delay=300
done
