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

OUTPUT="voice"
FORMAT="mp3"
BITRATE="128k"
SOURCE=""
GAIN="6dB"
NORMALIZE=1
PROBE=0

usage() {
    cat <<EOF
Usage: $0 -o name [-f mp3|wav] [-b bitrate] [-s source] [-g gain] [-n] [-p]

Records the currently active audio output (whatever is playing through the
default sink). Auto-detects the correct monitor source.

Options:
  -o NAME       Output basename (without extension)
  -f FORMAT     mp3 (default) or wav
  -b BITRATE    MP3 bitrate (default 128k)
  -s SOURCE     Override monitor source (default: auto-detect from default sink)
  -g GAIN       Pre-normalization gain (default 8dB; set 0dB to disable)
  -n            No normalization (raw capture)
  -p            Probe mode: 5s test recording, print levels, exit
  -h            Help

Notes:
  Pre-gain default (8dB) is tuned for an attenuated chain (e.g. Bluetooth sink
  at ~0.35 + app-level stream attenuation). Run -p after any sink or headphone
  change; chain attenuation is device-specific.

Examples:
  $0 -o lecture
  $0 -o music -f wav -g 6dB
  $0 -p                  # check levels before committing to a long recording
EOF
    exit 0
}

while getopts "o:f:b:s:g:nph" opt; do
    case "$opt" in
        o) OUTPUT="$OPTARG" ;;
        f) FORMAT="$OPTARG" ;;
        b) BITRATE="$OPTARG" ;;
        s) SOURCE="$OPTARG" ;;
        g) GAIN="$OPTARG" ;;
        n) NORMALIZE=0 ;;
        p) PROBE=1 ;;
        h) usage ;;
        *) usage ;;
    esac
done

# Auto-detect monitor of the default sink (what the user is actually hearing)
if [ -z "$SOURCE" ]; then
    DEFAULT_SINK=$(pactl get-default-sink)
    SOURCE="${DEFAULT_SINK}.monitor"
fi

# Verify the source exists before invoking ffmpeg
if ! pactl list sources short | awk '{print $2}' | grep -Fxq "$SOURCE"; then
    echo "Error: monitor source not found: $SOURCE" >&2
    echo "Available sources:" >&2
    pactl list sources short | awk '{print "  " $2}' >&2
    exit 1
fi

# Build audio filter chain
FILTER=""
if [ "$NORMALIZE" -eq 1 ]; then
    FILTER="volume=${GAIN},loudnorm=I=-16:TP=-1.5:LRA=11"
elif [ "$GAIN" != "0dB" ]; then
    FILTER="volume=${GAIN}"
fi

FORMAT=$(echo "$FORMAT" | tr '[:upper:]' '[:lower:]')

# Probe mode: short capture, report levels, exit
if [ "$PROBE" -eq 1 ]; then
    echo "Probing $SOURCE for 5 seconds..."
    PROBE_OUT=$(ffmpeg -hide_banner -nostats -loglevel info \
        -f pulse -i "$SOURCE" -t 5 -af "volumedetect" -f null - 2>&1) || true
    LEVELS=$(echo "$PROBE_OUT" | grep -E "mean_volume|max_volume" || true)
    if [ -z "$LEVELS" ]; then
        echo "No level data — source emitted silence or ffmpeg failed."
        echo
        echo "ffmpeg output (last 20 lines):"
        echo "$PROBE_OUT" | tail -20
    else
        echo "$LEVELS"
        echo
	echo "Current gain: -g ${GAIN}"
	echo
        echo "Reference:"
        echo "  mean_volume near -16 dB        good for voice"
        echo "  mean_volume below -25 dB       increase -g or raise sink volume"
        echo "  max_volume above -1 dB         reduce -g (risk of clipping)"
    fi
    exit 0
fi

# Assemble ffmpeg invocation
FILE="${OUTPUT}.${FORMAT}"
ARGS=(-f pulse -i "$SOURCE" -ac 2)
[ -n "$FILTER" ] && ARGS+=(-af "$FILTER")

case "$FORMAT" in
    mp3) ARGS+=(-c:a libmp3lame -b:a "$BITRATE") ;;
    wav) : ;;
    *)
        echo "Error: unsupported format '$FORMAT' (use mp3 or wav)" >&2
        exit 1
        ;;
esac

echo "Recording: $SOURCE"
echo "Filter:    ${FILTER:-(none)}"
echo "Output:    $FILE"
echo "Press Ctrl+C to stop."
echo

ffmpeg "${ARGS[@]}" "$FILE"
