#!/bin/bash
# Beacon Diagnostic Script
# Collects system info and container logs for troubleshooting.
# Bundles everything into a single .zip next to the script for easy emailing.

set -e

# Use USB mount point if available, otherwise use script's directory
SCRIPT_DIR="${BEACON_USB_MOUNT:-$(dirname "$0")}"
OUTPUT_DIR="${SCRIPT_DIR}/diagnostic-$(date +%Y%m%d-%H%M%S)"

mkdir -p "$OUTPUT_DIR/logs"

echo "=== Beacon Diagnostic ===" | tee "$OUTPUT_DIR/summary.txt"
echo "Date: $(date)" | tee -a "$OUTPUT_DIR/summary.txt"
echo "Output: $OUTPUT_DIR" | tee -a "$OUTPUT_DIR/summary.txt"
echo "" | tee -a "$OUTPUT_DIR/summary.txt"

# System info
echo "Collecting system info..."
{
    echo "=== System Info ==="
    echo "Hostname: $(hostname)"
    echo "Uptime: $(uptime)"
    echo "Kernel: $(uname -a)"
    echo ""
    echo "=== Memory ==="
    free -h
    echo ""
    echo "=== Disk ==="
    df -h
    echo ""
    echo "=== CPU ==="
    lscpu 2>/dev/null || cat /proc/cpuinfo | head -20
    echo ""
    echo "=== CPU Governor ==="
    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo "N/A"
} > "$OUTPUT_DIR/system-info.txt"

# Network info
echo "Collecting network info..."
{
    echo "=== Network Interfaces ==="
    ip -br addr
    echo ""
    echo "=== Routes ==="
    ip route
    echo ""
    echo "=== Beacon Network Config ==="
    cat /var/lib/beacon/network/interfaces.json 2>/dev/null || echo "Not found"
} > "$OUTPUT_DIR/network-info.txt"

# WiFi info
echo "Collecting wifi info..."
{
    echo "=== rfkill Status ==="
    rfkill list wifi 2>/dev/null || echo "rfkill not available"
    echo ""
    echo "=== wlan0 Interface ==="
    iw dev wlan0 info 2>/dev/null || echo "wlan0 not found"
    echo ""
    echo "=== hostapd Status ==="
    systemctl status hostapd 2>&1 || true
    echo ""
    echo "=== dnsmasq-wlan Status ==="
    dnsmasq 2>&1 || true
    echo ""
    echo "=== hostapd Configuration ==="
    cat /etc/hostapd/hostapd.conf 2>/dev/null || echo "Not found"
    echo ""
    echo "=== Connected WiFi Clients ==="
    iw dev wlan0 station dump 2>/dev/null || echo "No stations or interface unavailable"
    echo ""
    echo "=== DHCP Leases ==="
    cat /var/lib/misc/dnsmasq.leases 2>/dev/null || echo "No leases file"
} > "$OUTPUT_DIR/wifi-info.txt"

# Connectivity checks
echo "Checking connectivity..."
{
    DOMAINS="iot.hirebotics.io beacon.hirebotics.io beacon-api.hirebotics.io beacon-files.hirebotics.io"
    for domain in $DOMAINS; do
        echo "=== $domain ==="
        curl --silent --verbose --show-error --ipv4 --location --connect-timeout 5 --url "https://$domain" 2>&1 | head -100
        echo ""
    done
} > "$OUTPUT_DIR/connectivity.txt"

# Docker info
echo "Collecting Docker info..."
{
    echo "=== Docker Info ==="
    docker info 2>&1
    echo ""
    echo "=== Docker Images ==="
    docker images
    echo ""
    echo "=== Docker Containers ==="
    docker ps -a
} > "$OUTPUT_DIR/docker-info.txt"

# Container logs - mapped by name
echo "Collecting container logs..."
for container in $(docker ps -a --format '{{.Names}}'); do
    echo "  - $container"
    docker logs "$container" > "$OUTPUT_DIR/logs/${container}.log" 2>&1 || true
done

# Systemd service status - all beacon units
echo "Collecting service status..."
{
    echo "=== All Beacon Units ==="
    systemctl list-units --all 'beacon-*' 2>&1 || true
    echo ""

    # Status of each beacon unit
    for unit in $(systemctl list-units --all 'beacon-*' --no-legend | awk '{print $1}'); do
        echo "=== $unit ==="
        systemctl status "$unit" 2>&1 || true
        echo ""
    done

    echo "=== Failed Units ==="
    systemctl --failed 2>&1 || true
} > "$OUTPUT_DIR/services.txt"

# USB autorun logs
echo "Collecting USB autorun logs..."
{
    echo "=== USB Autorun Log ==="
    cat /var/log/beacon-usb-autorun.log 2>/dev/null || echo "Not found"
    echo ""
    echo "=== USB Executions Log ==="
    cat /var/log/beacon-usb-executions.log 2>/dev/null || echo "Not found"
} > "$OUTPUT_DIR/usb-autorun.txt"

# Journal logs (last boot)
echo "Collecting journal logs..."
journalctl -b --no-pager > "$OUTPUT_DIR/journal.log" 2>&1 || true

# SQLite database from cloud-connector data mount
echo "Collecting database..."
DB_DIR="/data/beacon/cloud-connector/data"
DB_NAME="database.sqlite"
if [ -f "$DB_DIR/$DB_NAME" ]; then
    cp -p "$DB_DIR/$DB_NAME" "$OUTPUT_DIR/" 2>/dev/null && echo "  - $DB_NAME"
    cp -p "$DB_DIR/$DB_NAME-wal" "$OUTPUT_DIR/" 2>/dev/null && echo "  - $DB_NAME-wal"
    cp -p "$DB_DIR/$DB_NAME-shm" "$OUTPUT_DIR/" 2>/dev/null && echo "  - $DB_NAME-shm"
else
    echo "  - database not found at $DB_DIR/$DB_NAME"
fi

# Finalize the summary before compressing so the archived copy is complete.
echo ""
echo "=== Complete ===" | tee -a "$OUTPUT_DIR/summary.txt"
echo "Files collected in: $OUTPUT_DIR" | tee -a "$OUTPUT_DIR/summary.txt"
ls -la "$OUTPUT_DIR/" | tee -a "$OUTPUT_DIR/summary.txt"

# Compress everything into a single file for easy transfer to Beacon Support.
echo ""
echo "Compressing diagnostic into a single file..."
ARCHIVE_NAME="$(basename "$OUTPUT_DIR").zip"

# zip stores paths relative to the working directory, so run it from the parent
# (the USB mount / script dir) to keep a clean "diagnostic-<timestamp>/" folder
# inside the archive. Guarded by 'if' so a zip failure can't abort under 'set -e'.
if ( cd "$SCRIPT_DIR" && zip -rq "$ARCHIVE_NAME" "$(basename "$OUTPUT_DIR")" ); then
    # Success: drop the uncompressed folder so only the single .zip remains.
    # Nothing loose to accidentally modify, and one obvious file to email.
    rm -rf "$OUTPUT_DIR" || true
    echo ""
    echo "=== Done ==="
    echo "Diagnostic saved to a single file:"
    echo "  ${SCRIPT_DIR}/${ARCHIVE_NAME}"
    echo ""
    echo "Please email this .zip file to Hirebotics support."
else
    # Compression failed for some reason; keep the folder so no data is lost.
    echo ""
    echo "=== Done (could not create .zip) ==="
    echo "Please email the entire folder to Hirebotics support:"
    echo "  $OUTPUT_DIR"
fi
