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

IFACE="${1:-}"
ACTION="${2:-}"

# The timer watchdog is the single owner of automatic Wi-Fi recovery. The
# dispatcher only observes a successful manual client activation so a user who
# connects through NetworkManager/VNC can leave explicit hotspot-only mode.
# It must never launch nmcli recovery commands from NetworkManager callbacks:
# those commands produce more callbacks and can create an unbounded event loop.
if [[ "$ACTION" != "up" ]]; then
    exit 0
fi

COORDINATION_LOCK_FILE="/run/pins-wifi-coordination.lock"
WIFI_CONFIG_FILE="/opt/pinsdaemon/app/wifi_config.json"
LOG_TAG="pins-wifi-recovery"
DEFAULT_WIFI_INTERFACE="wlan0"
LOCAL_LOG_DIR="${PINSDAEMON_LOG_DIR:-/opt/pinsdaemon/logs}"
LOCAL_LOG_RETENTION_DAYS="${PINSDAEMON_LOG_RETENTION_DAYS:-5}"

prune_local_logs() {
    mkdir -p "$LOCAL_LOG_DIR" 2>/dev/null || return 0
    find "$LOCAL_LOG_DIR" -maxdepth 1 -type f -name 'wifi-recovery-*.log' -mtime +"$((LOCAL_LOG_RETENTION_DAYS - 1))" -delete 2>/dev/null || true
}

log() {
    local message="$*"
    logger -t "$LOG_TAG" "$message"
    prune_local_logs
    printf "%s %s\n" "$(date --iso-8601=seconds)" "$message" >>"$LOCAL_LOG_DIR/wifi-recovery-$(date +%F).log" 2>/dev/null || true
}

read_configured_state() {
    python3 - "$WIFI_CONFIG_FILE" "$DEFAULT_WIFI_INTERFACE" <<'PY'
import json
import os
import re
import sys

path = sys.argv[1]
default_iface = sys.argv[2]
valid = re.compile(r"^[A-Za-z0-9._-]+$")

client = default_iface
hotspot = default_iface
desired_mode = "auto"

if os.path.exists(path):
    try:
        with open(path, "r", encoding="utf-8") as source:
            data = json.load(source)
        if isinstance(data, dict):
            candidate_client = data.get("client_interface")
            candidate_hotspot = data.get("hotspot_interface")
            candidate_mode = data.get("desired_mode")
            if isinstance(candidate_client, str) and valid.fullmatch(candidate_client.strip()):
                client = candidate_client.strip()
            if isinstance(candidate_hotspot, str) and valid.fullmatch(candidate_hotspot.strip()):
                hotspot = candidate_hotspot.strip()
            if isinstance(candidate_mode, str) and candidate_mode.strip().lower() in {"auto", "hotspot"}:
                desired_mode = candidate_mode.strip().lower()
    except Exception:
        pass

print(client)
print(hotspot)
print(desired_mode)
PY
}

mapfile -t STATE < <(read_configured_state)
CLIENT_IFACE="${STATE[0]:-$DEFAULT_WIFI_INTERFACE}"
HOTSPOT_IFACE="${STATE[1]:-$CLIENT_IFACE}"
DESIRED_MODE="${STATE[2]:-auto}"

if [[ "$IFACE" != "$CLIENT_IFACE" || "$CLIENT_IFACE" != "$HOTSPOT_IFACE" || "$DESIRED_MODE" != "hotspot" ]]; then
    exit 0
fi

if ! command -v flock >/dev/null 2>&1; then
    log "Cannot persist manual Wi-Fi mode hand-off safely: flock is unavailable"
    exit 0
fi

exec 9>"$COORDINATION_LOCK_FILE"
if ! flock -n 9; then
    exit 0
fi

is_wifi_client_active() {
    while IFS=: read -r profile_uuid profile_type profile_iface; do
        [[ "$profile_type" == "802-11-wireless" && "$profile_iface" == "$CLIENT_IFACE" ]] || continue
        profile_mode="$(nmcli -g 802-11-wireless.mode connection show uuid "$profile_uuid" 2>/dev/null || true)"
        if [[ "$profile_mode" != "ap" ]]; then
            return 0
        fi
    done < <(nmcli -t -f UUID,TYPE,DEVICE connection show --active 2>/dev/null)
    return 1
}

persist_auto_mode() {
    python3 - "$WIFI_CONFIG_FILE" <<'PY'
import json
import os
import tempfile
import sys

path = sys.argv[1]
with open(path, "r", encoding="utf-8") as source:
    config = json.load(source)
config["desired_mode"] = "auto"
directory = os.path.dirname(path)
fd, temporary = tempfile.mkstemp(prefix=".wifi-config-", suffix=".tmp", dir=directory)
try:
    with os.fdopen(fd, "w", encoding="utf-8") as target:
        json.dump(config, target, indent=2)
        target.write("\n")
        target.flush()
        os.fsync(target.fileno())
    os.chmod(temporary, 0o600)
    os.replace(temporary, path)
finally:
    try:
        os.unlink(temporary)
    except FileNotFoundError:
        pass
PY
}

if is_wifi_client_active; then
    if persist_auto_mode; then
        log "Wi-Fi client activated manually on ${CLIENT_IFACE}; returning network mode to auto"
    else
        log "Failed to persist automatic mode after manual Wi-Fi client activation"
    fi
fi

exit 0
