#!/bin/bash

# =============================================================================
# Batch Audio Compressor - 96 kbps AAC
# Preserves folder structure, uses ffmpeg + GNU parallel + hardware acceleration
# =============================================================================

set -euo pipefail

# -------------------------------
# Configuration
# -------------------------------
SOURCE_DIR="${1:-./audio_source}"
OUTPUT_DIR="${2:-./audio_96kbps}"
LOG_FILE="./compression.log"
#NUM_JOBS="1"
NUM_JOBS="${PARALLEL_JOBS:-$(nproc)}" # Use all cores by default

# Supported input audio extensions (lowercase)
declare -a AUDIO_EXTS=("wav" "flac" "aiff" "aif" "mp3" "m4a" "ogg" "wma" "ac3" "alac")

# -------------------------------
# Functions
# -------------------------------

log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}

detect_hw_accel() {

  echo "vdpau"
  return

  # Cuda?
  if ffmpeg -hwaccels 2>/dev/null | grep -q cuda; then
    echo "cuda"
  # Try to detect available hardware acceleration
  elif ffmpeg -hwaccels 2>/dev/null | grep -q vaapi; then
    echo "vaapi"
  elif ffmpeg -buildconf 2>&1 | grep -q "enable-vdpau"; then
    echo "vdpau"
  elif [[ "$(uname)" == "Darwin" ]] && ffmpeg -codecs 2>/dev/null | grep -q 'h264.* videotoolbox'; then
    echo "videotoolbox"
  else
    echo "none"
  fi
}

get_hw_args() {
  local hw_accel="$1"
  local input_file="$2"

  case "$hw_accel" in
  "vaapi")
    echo "-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' -c:a aac -b:a 64k"
    ;;
  "videotoolbox")
    # Apple's VideoToolbox (macOS) — fast for H.264, less useful for audio, but can accelerate some codecs
    # Note: Audio encoding isn't accelerated, but we include for completeness if video is present
    echo "-c:a aac -b:a 64k -c:v h264_videotoolbox"
    ;;
  *)
    echo "-c:a libmp3lame -b:a 64k" # Fallback to software encoding
    ;;
  esac
}

# -------------------------------
# Input validation
# -------------------------------
if [[ ! -d "$SOURCE_DIR" ]]; then
  echo "Error: Source directory does not exist: $SOURCE_DIR"
  echo "Usage: $0 <source_dir> <output_dir>"
  exit 1
fi

mkdir -p "$OUTPUT_DIR"
log "Starting compression of '$SOURCE_DIR' -> '$OUTPUT_DIR' at 96 kbps AAC"
log "Using $NUM_JOBS parallel jobs"

# -------------------------------
# Detect hardware acceleration
# -------------------------------
HW_ACCEL="$(detect_hw_accel)"
log "Hardware acceleration detected: $HW_ACCEL"

# -------------------------------
# Find all audio files and process them via parallel
# -------------------------------
# Export functions and variables for GNU parallel
export -f get_hw_args
export SOURCE_DIR
export OUTPUT_DIR
export HW_ACCEL

# Build find command for all audio extensions
find_cmd="find \"$SOURCE_DIR\" -type f \\( "
for ext in "${AUDIO_EXTS[@]}"; do
  find_cmd+=" -iname \"*.${ext}\" -o"
done
# Replace trailing "-o" with "\\)"
find_cmd="${find_cmd% -o} \\)"

# Use eval to execute the dynamic find command and pipe to parallel
eval "$find_cmd" | sort | parallel -j"$NUM_JOBS" --progress --bar --joblog parallel_jobs.log --eta '
    input_file="{}"
    rel_path="${SOURCE_DIR:+${input_file#"$SOURCE_DIR"/}}"
    output_file="'$OUTPUT_DIR'/${rel_path%.*}.mp3"

    # Create output directory if needed
    mkdir -p "$(dirname "$output_file")"

    if [[ -f "$output_file" ]]; then
        echo "Skipped (exists): $rel_path"
        exit 0
    fi

    hw_args=$(get_hw_args "'$HW_ACCEL'" "$input_file")
    ffmpeg -v warning -stats \
           -i "$input_file" \
           $hw_args \
           -y "$output_file" \
           && echo "Converted: $rel_path"
'

log "Compression complete. Output saved to: $OUTPUT_DIR"
