#!/usr/bin/env bash
# process_butt_recording.sh
#
# USAGE:
#   ./process_butt_recording.sh <input_file>
#   Accepts audio files (mp3, wav, ogg, flac...) or video files (mp4, mkv...).
#   For video files, only the audio track is extracted.
#   All paths must be POSIX-style (in WSL: /mnt/c/... or ~/)
#   Output files are written to the current working directory.
#
# RUNTIME DEPENDENCIES (must be in PATH):
#   ffmpeg      — audio conversion + metadata  (apt install ffmpeg | brew install ffmpeg)
#   metaflac    — FLAC cover art embedding     (apt install flac   | brew install flac)
#
# FILE DEPENDENCIES (relative to this script's location):
#   ./albumart.png  — front cover image (any size; 1:1 recommended)
#
# OUTPUT FORMAT:
#   FLAC: ∆•MIX_100.flac  —  metadata title: ∆•MIX 100
#   MP3:  ∆•MIX_100.mp3   —  320 CBR, ID3v2, same metadata + cover art

set -euo pipefail

# Ensure Unicode patterns work consistently across macOS/Linux/WSL
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ALBUMART="$SCRIPT_DIR/albumart.png"

# --- Input validation ---
if [ $# -lt 1 ]; then
    echo "Usage: $0 <input_file>"
    exit 1
fi
input="$1"
if [ ! -f "$input" ]; then
    echo "ERROR: input file not found: $input"
    exit 1
fi

# --- Video container check: extract audio-only before processing ---
# If input has a video stream, demuxing interleaved video+audio is ~300x slower
# for silenceremove. Stream-copy just the audio track first (fast, lossless).
_tmp_audio=""
if ffprobe -v error -select_streams v:0 -show_entries stream=codec_type \
        -of csv=p=0 "$input" 2>/dev/null | grep -q video; then
    echo "=== Video container detected — extracting audio track (stream copy) ==="
    _tmp_audio="$(mktemp --suffix=.flac)"
    ffmpeg -y -i "$input" -vn -c:a copy "$_tmp_audio"
    input="$_tmp_audio"
fi
trap '[ -n "$_tmp_audio" ] && rm -f "$_tmp_audio"' EXIT

# --- Date extraction ---
# Supports two filename date formats:
#   YYYYMMDD (8 consecutive digits) — BUTT default: stream_YYYYMMDD_HHMMSS.ext
#   YYYY-MM-DD (dashed)             — OBS default:  2026-04-12 22-00-00.mp4
# Prompts for manual entry if neither is found.
# NOTE: use $1 (original filename), not $input (may be temp file after video extraction)
basename_input=$(basename "$1")
dashed_date=$(echo "$basename_input" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1 || true)
raw_date=$(echo "$basename_input" | grep -oE '[0-9]{8}' | head -1 || true)

if [ -n "$dashed_date" ]; then
    date_string="$dashed_date"
elif [ -n "$raw_date" ]; then
    date_string="${raw_date:0:4}-${raw_date:4:2}-${raw_date:6:2}"
else
    echo "WARNING: could not find date in filename."
    read -rp "Enter date manually (YYYY-MM-DD): " date_string
    if ! echo "$date_string" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'; then
        echo "ERROR: invalid date format '$date_string' — expected YYYY-MM-DD"
        exit 1
    fi
fi

# --- Mix number extraction ---
# Matches ∆•MIXnn or ∆•MIXnnn (2-3 digits). Prompts if not found.
# Uses POSIX character classes + explicit chars to stay portable across grep variants.
mixnumber_string=$(echo "$basename_input" | grep -oP '[\x{2206}\x{0394}]\x{2022}MIX\d{2,3}' 2>/dev/null \
    || echo "$basename_input" | grep -oE '[∆Δ]•MIX[0-9]{2,3}' || true)
mixnumber_raw="${mixnumber_string##*MIX}"

echo "Detected mix: '${mixnumber_string:-<none>}'  →  number: '${mixnumber_raw:-<none>}'"

if [ -z "$mixnumber_raw" ]; then
    read -rp "Could not detect mix number. Enter it manually: " mixnumber_raw
fi

# Strip any leading zeros before re-padding (avoids octal issues with printf)
mixnumber_raw=$((10#${mixnumber_raw}))
mixnumber=$(printf '%03d' "$mixnumber_raw")

# Output filenames and metadata
title="∆•MIX $mixnumber"
flac_out="∆•MIX_${mixnumber}.flac"
mp3_out="∆•MIX_${mixnumber}.mp3"

echo "Date:        $date_string"
echo "Title:       $title"
echo "FLAC output: $flac_out"
echo "MP3 output:  $mp3_out"
echo ""

# --- Detect input bit depth → preserve it in FLAC output ---
# silenceremove processes as float internally; without -sample_fmt ffmpeg upcasts to 32-bit.
# FLAC encoder uses s16 for 16-bit, s32 for 24-bit (stored as 24-bit in the file).
_bit_depth=$(ffprobe -v error -select_streams a:0 \
    -show_entries stream=bits_per_raw_sample \
    -of csv=p=0 "$input" 2>/dev/null | head -1 || true)
if [ "$_bit_depth" = "16" ]; then
    _sample_fmt="-sample_fmt s16"
else
    _sample_fmt="-sample_fmt s32"
fi
echo "Input bit depth: ${_bit_depth:-unknown} → FLAC sample_fmt: $_sample_fmt"

# --- Step 1: Convert + trim silence → FLAC ---
echo "=== Converting to FLAC ==="
ffmpeg -y -i "$input" \
    -af "silenceremove=start_periods=1:start_threshold=-50dB:start_duration=3:start_silence=4:detection=rms:stop_periods=1:stop_threshold=-60dB:stop_duration=7:stop_silence=0.5" \
    -c:a flac $_sample_fmt \
    -metadata artist="∆•RYZ" \
    -metadata album="∆•MIX" \
    -metadata album_artist="∆•RYZ" \
    -metadata date="$date_string" \
    -metadata title="$title" \
    -metadata comment="deltaryz.com" \
    -metadata track="$mixnumber_raw" \
    "$flac_out"

# --- Step 2: Embed cover art in FLAC ---
if [ -f "$ALBUMART" ]; then
    echo "=== Embedding cover art in FLAC ==="
    metaflac --import-picture-from="$ALBUMART" "$flac_out"
else
    echo "WARNING: $ALBUMART not found — FLAC has no cover art"
fi

# --- Step 3: FLAC → MP3 320 CBR with cover art ---
echo "=== Converting to MP3 ==="
if [ -f "$ALBUMART" ]; then
    ffmpeg -y -i "$flac_out" -i "$ALBUMART" \
        -map 0:a -map 1:v \
        -c:a libmp3lame -b:a 320k \
        -c:v copy \
        -id3v2_version 3 \
        -metadata:s:v title="Album cover" \
        -metadata:s:v comment="Cover (front)" \
        "$mp3_out"
else
    ffmpeg -y -i "$flac_out" \
        -c:a libmp3lame -b:a 320k \
        "$mp3_out"
    echo "WARNING: $ALBUMART not found — MP3 has no cover art"
fi

echo ""
echo "=== Done ==="
echo "  $flac_out"
echo "  $mp3_out"
