#!/bin/bash
set -euo pipefail
DEFAULTS="/etc/default/nivato-logger"
[ -f "$DEFAULTS" ] && . "$DEFAULTS"

IFACE="${1:?interface}"
SSID="${2:?ssid}"
PASSWORD=""
IP="192.168.1.254"

# Argumenty:
#   wifi-hotspot-start IFACE SSID PASSWORD [IP]   — legacy (hotspot-boot)
#   wifi-hotspot-start IFACE SSID IP              — hasło na stdin (Java)
#   wifi-hotspot-start IFACE SSID                 — hasło na stdin, IP domyślne
if [ "$#" -ge 4 ]; then
    PASSWORD="${3:?password}"
    IP="${4}"
elif [ "$#" -eq 3 ]; then
    if [[ "$3" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        IP="$3"
        if [ ! -t 0 ]; then
            PASSWORD="$(cat || true)"
        fi
    else
        PASSWORD="$3"
    fi
elif [ ! -t 0 ]; then
    PASSWORD="$(cat || true)"
fi

if [ -z "$PASSWORD" ]; then
    echo "Brak hasła hotspotu (argv lub stdin)" >&2
    exit 1
fi

IP="${IP:-192.168.1.254}"
REG_DOMAIN="${NIVATO_WIFI_REG_DOMAIN:-PL}"
CAPTIVE_DNSMASQ_DIR="/etc/NetworkManager/dnsmasq-shared.d"
CAPTIVE_DNSMASQ_FILE="$CAPTIVE_DNSMASQ_DIR/nivato-captive-portal.conf"

if [ -x /usr/sbin/iw ]; then
    /usr/sbin/iw reg set "$REG_DOMAIN" 2>/dev/null || true
fi

/usr/bin/nmcli device set "$IFACE" managed yes 2>/dev/null || true
/usr/bin/nmcli radio wifi on 2>/dev/null || true

# Disable autoconnect on all WiFi client profiles before disconnecting the interface.
# Without this, NM immediately tries to reconnect as a client while we're switching
# to AP mode, causing a race condition that leaves the interface in a broken state.
while IFS= read -r conn; do
    [ "$conn" = "Hotspot" ] && continue
    /usr/bin/nmcli connection modify "$conn" connection.autoconnect no 2>/dev/null || true
done < <(/usr/bin/nmcli -t -f NAME,TYPE connection show 2>/dev/null | awk -F: '$2 == "802-11-wireless" { print $1 }')

/usr/bin/nmcli dev disconnect "$IFACE" 2>/dev/null || true
sleep 1
/usr/bin/nmcli connection delete Hotspot 2>/dev/null || true

# Captive portal support: while the setup hotspot is active, resolve all
# regular DNS names to the device. Phones/laptops then reach our local HTTP
# endpoints used by Android/iOS/Windows captive-network detection.
if mkdir -p "$CAPTIVE_DNSMASQ_DIR" 2>/dev/null; then
    {
        printf '# Generated by nivato-logger setup hotspot.\n'
        printf 'address=/#/%s\n' "$IP"
    } > "$CAPTIVE_DNSMASQ_FILE" 2>/dev/null || true
fi

/usr/bin/nmcli connection add \
    type wifi \
    ifname "$IFACE" \
    con-name Hotspot \
    ssid "$SSID" \
    mode ap \
    802-11-wireless.band bg \
    802-11-wireless.channel 6 \
    ipv4.method shared \
    ipv4.addresses "${IP}/24" \
    wifi-sec.key-mgmt wpa-psk \
    wifi-sec.psk "$PASSWORD" \
    connection.autoconnect no

# Windows potrafi proponować "PIN z routera" przy sieciach z WPS. Hotspot
# konfiguracyjny używa zwykłego hasła WPA, więc WPS wyłączamy, jeśli dana
# wersja NetworkManagera udostępnia tę właściwość.
/usr/bin/nmcli connection modify Hotspot wifi-sec.wps-method disabled 2>/dev/null || true

for attempt in 1 2 3; do
    if /usr/bin/nmcli connection up Hotspot; then
        exit 0
    fi
    /usr/bin/nmcli dev disconnect "$IFACE" 2>/dev/null || true
    /usr/bin/nmcli device set "$IFACE" managed yes 2>/dev/null || true
    /usr/bin/nmcli radio wifi on 2>/dev/null || true
    sleep 2
done

rm -f "$CAPTIVE_DNSMASQ_FILE" 2>/dev/null || true
exit 1
