# Klubhaus Doorbell - justfile
# Run with: just <recipe>
# Set BOARD: just BOARD=esp32-32e-4 compile

# Default recipe - show help
default:
    @just --list

# Set default BOARD
BOARD := "esp32-32e-4"

# Helper to source board config
# just passes args as positional, so we source in each recipe

# Compile firmware
compile:
    #!/usr/bin/env bash
    set -e
    source ./boards/{{BOARD}}/board-config.sh
    
    # Only regenerate compile_commands.json if needed (board changed or first run)
    NEED_GEN=false
    if [ ! -f compile_commands.json ]; then
        NEED_GEN=true
    elif [ ! -f .board-last ] || [ "$(cat .board-last)" != "{{BOARD}}" ]; then
        NEED_GEN=true
    fi
    
    if [ "$NEED_GEN" = "true" ]; then
        rm -rf /tmp/arduino-build
        arduino-cli compile --only-compilation-database --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --build-path /tmp/arduino-build ./boards/{{BOARD}}
        cp /tmp/arduino-build/compile_commands.json .
        echo "{{BOARD}}" > .board-last
        echo "[OK] Generated compile_commands.json for {{BOARD}}"
    else
        echo "[SKIP] compile_commands.json already up to date for {{BOARD}}"
    fi
    
    arduino-cli compile --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --warnings default ./boards/{{BOARD}}

# Upload firmware
upload: kill
    #!/usr/bin/env bash
    set -e
    source ./boards/{{BOARD}}/board-config.sh
    arduino-cli upload --fqbn "$FQBN" --port "$PORT" ./boards/{{BOARD}}

# Kill processes using serial port
kill:
    #!/usr/bin/env bash
    set +e
    source ./boards/{{BOARD}}/board-config.sh
    PORT="${PORT:-$PORT}"
    echo "Killing processes on $PORT..."
    fuser -k "$PORT" 2>/dev/null || true
    for pid in $(pgrep -f "monitor-agent.py.*{{BOARD}}" 2>/dev/null || true); do
        echo "Killing monitor-agent.py (PID: $pid)..."
        kill "$pid" 2>/dev/null || true
    done
    rm -f "/tmp/doorbell-{{BOARD}}.lock" 2>/dev/null || true
    sleep 1
    echo "[OK] Killed processes for {{BOARD}}"

# Monitor raw serial
monitor-raw: kill
    #!/usr/bin/env bash
    source ./boards/{{BOARD}}/board-config.sh
    PORT="${PORT:-$PORT}"
    TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")"
    arduino-cli monitor -p "$TARGET" --config baudrate=115200

# Show tio command
monitor-tio: kill
    #!/usr/bin/env bash
    source ./boards/{{BOARD}}/board-config.sh
    PORT="${PORT:-$PORT}"
    TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")"
    echo "Run: tio --map INLCRNL $TARGET -e"

# Monitor with JSON logging
monitor: kill
    #!/usr/bin/env bash
    python3 ./scripts/monitor-agent.py "{{BOARD}}" &

# Tail colored logs
watch:
    #!/usr/bin/env bash
    tail -f "/tmp/doorbell-{{BOARD}}.jsonl" | while read -r line; do
        ts=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['ts'])" 2>/dev/null)
        txt=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['line'])" 2>/dev/null)
        if [[ "$txt" == *"[STATE]"* ]]; then
            echo -e "\033[1;35m[$ts]\033[0m $txt"
        elif [[ "$txt" == *"[ADMIN]"* ]]; then
            echo -e "\033[1;36m[$ts]\033[0m $txt"
        elif [[ "$txt" == *"[TOUCH]"* ]]; then
            echo -e "\033[1;33m[$ts]\033[0m $txt"
        elif [[ "$txt" == *"ALERT"* ]]; then
            echo -e "\033[1;31m[$ts]\033[0m $txt"
        else
            echo "[$ts] $txt"
        fi
    done

# Send command to device
cmd command:
    #!/usr/bin/env bash
    echo -n "{{command}}" > "/tmp/doorbell-{{BOARD}}-cmd.fifo"
    echo "[SENT] {{command}}"

# Show device state
state:
    @cat "/tmp/doorbell-{{BOARD}}-state.json"

# Detect connected board
detect:
    #!/usr/bin/env bash
    bash ./scripts/detect-device.sh

# Install shared libraries
install-libs-shared:
    #!/usr/bin/env bash
    ./scripts/install-shared.sh

# Install all libraries
install: install-libs-shared
    #!/usr/bin/env bash
    ./boards/{{BOARD}}/install.sh
    arduino-cli core install esp32:esp32

# Clean build artifacts
clean:
    #!/usr/bin/env bash
    rm -rf vendor/
    rm -rf .cache/
    rm -rf boards/esp32-32e/build
    rm -rf boards/esp32-32e-4/build
    rm -rf boards/esp32-s3-lcd-43/build
    rm -f .board-last
    echo "[OK] Build artifacts cleaned"

# Clean temporary files (monitor logs, FIFOs, state files)
clean-temp:
    #!/usr/bin/env bash
    rm -f /tmp/doorbell-esp32-32e.jsonl /tmp/doorbell-esp32-32e-state.json /tmp/doorbell-esp32-32e-cmd.fifo
    rm -f /tmp/doorbell-esp32-32e-4.jsonl /tmp/doorbell-esp32-32e-4-state.json /tmp/doorbell-esp32-32e-4-cmd.fifo
    rm -f /tmp/doorbell-esp32-s3-lcd-43.jsonl /tmp/doorbell-esp32-s3-lcd-43-state.json /tmp/doorbell-esp32-s3-lcd-43-cmd.fifo
    rm -f .board-last
    echo "[OK] Temp files cleaned"

# Clean Arduino cache
arduino-clean:
    #!/usr/bin/env bash
    echo "Checking ~/.arduino15..."
    du -sh ~/.arduino15/staging 2>/dev/null || echo "No staging folder"
    du -sh ~/.arduino15/packages 2>/dev/null || echo "No packages folder"
    read -p "Delete staging + packages folders? [y/N] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        rm -rf ~/.arduino15/staging
        rm -rf ~/.arduino15/packages
        echo "[OK] Arduino staging + packages cleared"
    else
        echo "Aborted"
    fi

# Format code
format:
    #!/usr/bin/env bash
    clang-format -i --style=file \
        boards/esp32-32e/*.cpp \
        boards/esp32-32e/*.h \
        boards/esp32-32e/*.ino \
        boards/esp32-32e-4/*.cpp \
        boards/esp32-32e-4/*.h \
        boards/esp32-32e-4/*.ino \
        boards/esp32-s3-lcd-43/*.cpp \
        boards/esp32-s3-lcd-43/*.h \
        boards/esp32-s3-lcd-43/*.ino \
        libraries/KlubhausCore/src/*.cpp \
        libraries/KlubhausCore/src/*.h \
        libraries/KlubhausCore/*.properties

# Generate crush config
gen-crush-config:
    #!/usr/bin/env bash
    set -e
    source ./boards/{{BOARD}}/board-config.sh
    printf '{\n  "lsp": {\n    "arduino": {\n      "command": "arduino-language-server",\n      "args": ["-fqbn", "%s"]\n    },\n    "cpp": {\n      "command": "clangd"\n    }\n  }\n}\n' "$FQBN" > .crush.json
    echo "[OK] Generated .crush.json with FQBN: $FQBN"
