#!/bin/bash

# Config
FREQ=4 # Checks (and animations) per second
DELAY=0.25 # Inverse of FREQ
TIMEOUT=5 # Timeout (in seconds) for virtual TTY creation

# Device condig
DEVICE="/dev/ttyACM0"  # Change if needed
BAUDRATE=115200
VIRTUAL_TTY="/tmp/virtual_tty"

# Wait spinner
propeller=( "/" "-" "\\" "|" )
index=0

# Cleanup function to stop processes on exit
cleanup() {
    echo ""
    echo "Exiting: Stopping processes..."
    [[ -n "$SOCAT_PID" ]] && kill $SOCAT_PID 2>/dev/null
    [[ -n "$CAT_PID" ]] && kill $CAT_PID 2>/dev/null
    wait $SOCAT_PID $CAT_PID 2>/dev/null
    echo "Done."
    exit 0
}

# Trap SIGINT (CTRL+C) to call cleanup function
trap cleanup SIGINT

while true; do
    printf "Auto Serial Monitor: Waiting for device $DEVICE ... "
    until [ -e "$DEVICE" ]; do
        printf "${propeller[$index]}"
        ((index = (index + 1) % 4)) # 4 is the number of animation frames
        sleep $DELAY
        printf "\b" # Backspace to overwrite previous spinner
    done
    echo "✔ Connected! Starting monitor..."

    # Start socat (muted output)
    socat -d -d $DEVICE,raw,echo=0 PTY,raw,echo=0,link=$VIRTUAL_TTY &> /dev/null &
    SOCAT_PID=$!

    # Wait for virtual TTY with a timeout
    TRIES=$((TIMEOUT * FREQ)) # Eg. 3s timeout with 4 tries/s = 12 tries

    until [ -e "$VIRTUAL_TTY" ] || [ $TRIES -le 0 ]; do
        sleep $DELAY
        ((TRIES--))
    done

    if [ ! -e "$VIRTUAL_TTY" ]; then
        echo "Error: Virtual TTY not created. Restarting..."
        kill $SOCAT_PID 2>/dev/null
        wait $SOCAT_PID 2>/dev/null
        continue
    fi
    echo ""

    # Monitor virtual TTY (muted output)
    cat "$VIRTUAL_TTY" 2>/dev/null &
    CAT_PID=$!

    # Wait for disconnection
    inotifywait -qq -e delete "$DEVICE"
    echo ""
    echo "Device disconnected."
    kill $SOCAT_PID $CAT_PID >/dev/null 2>&1
    wait $SOCAT_PID $CAT_PID 2>/dev/null
    echo "Monitor stopped."
    sleep 1
done

