#!/usr/bin/env bash
# tidal-ardour-autoroute — keep SuperDirt orbits wired to their Ardour tracks.
#
# SuperDirt emits stereo orbit pairs on SuperCollider:out_N. Orbit k (1-based)
# is the pair (out_{2k-1}, out_{2k}). Ardour has stereo tracks "Tidal NN".
#
# Rules (re-applied every $INTERVAL s, idempotent):
#   ADD:   SuperCollider:out_{2k-1} -> ardour:Tidal {NN}/audio_in 1
#          SuperCollider:out_{2k}   -> ardour:Tidal {NN}/audio_in 2
#   PRUNE: drop every SuperCollider:out_* -> <hardware>:playback_* link.
#          In this multichannel setup SC never feeds hardware directly —
#          monitoring is via Ardour Master. sclang/SuperDirt re-adds the
#          orbit-0 monitor (out_1/out_2 -> Headphones) on (re)boot; this kills it.
#
# Track numbers are auto-detected from the live graph, so adding/removing
# "Tidal NN" tracks in Ardour needs no edit here. pw-link "File exists" /
# missing-port errors are expected and ignored.

set -u

SC="SuperCollider"
INTERVAL="${TIDAL_AUTOROUTE_INTERVAL:-2}"

link() {  # $1 = source port, $2 = dest port ; silent (already-linked is fine)
    pw-link "$1" "$2" 2>/dev/null
}

# Print the set of Ardour "Tidal NN" track numbers currently present.
tidal_track_numbers() {
    pw-link -i 2>/dev/null \
        | grep -oE "ardour:Tidal [0-9]+/audio_in 1" \
        | grep -oE "[0-9]+" | sort -un
}

# Print "src<TAB>dest" for every SuperCollider:out_* -> hardware playback link.
sc_hw_playback_links() {
    pw-link -lo 2>/dev/null | awk -v sc="$SC" '
        /^[^ \t]/ { src = $0; next }                       # non-indented = source port
        index(src, sc ":out_") == 1 && /playback_/ {       # indented hw-playback dest
            dst = $0; sub(/^[ \t]*\|?->? */, "", dst);
            print src "\t" dst
        }'
}

reconcile() {
    # ADD: orbit pair -> matching Tidal track
    while read -r nn; do
        [ -n "${nn:-}" ] || continue
        k=$((10#$nn))                 # strip leading zero (NN -> k)
        l=$((2 * k - 1)); r=$((2 * k))
        link "$SC:out_$l" "ardour:Tidal $nn/audio_in 1"
        link "$SC:out_$r" "ardour:Tidal $nn/audio_in 2"
    done < <(tidal_track_numbers)

    # PRUNE: SuperCollider must never reach hardware playback directly
    while IFS=$'\t' read -r src dst; do
        [ -n "${src:-}" ] && [ -n "${dst:-}" ] && pw-link -d "$src" "$dst" 2>/dev/null
    done < <(sc_hw_playback_links)
}

echo "tidal-ardour-autoroute: reconciling orbit->track every ${INTERVAL}s"
while :; do
    reconcile
    sleep "$INTERVAL"
done
