#!/bin/bash
set -euo pipefail

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
umask 077

IFACE="wghub"
SOURCE="/root/wgfiles/peers.conf"
BOOT="/etc/wireguard/wgui/wghub.conf"

exec 9>/root/wgfiles/wgui.lock

lock_tries=0
until flock -n -x 9; do
    lock_tries=$((lock_tries + 1))
    if (( lock_tries >= 10 )); then
        echo "Nu am putut obtine lock-ul pentru peers.conf in 10 secunde." >&2
        exit 1
    fi
    sleep 1
done

sleep 1

work=$(mktemp -d /run/wgui-apply.XXXXXX)
persist_tmp=""

cleanup() {
    rm -rf -- "$work"
    if [[ -n "$persist_tmp" ]]; then
        rm -f -- "$persist_tmp"
    fi
}
trap cleanup EXIT

cp -- "$SOURCE" "$work/source.conf"

# Sectiunea Interface provine exclusiv din configuratia root.
awk '
    /^[[:space:]]*\[Peer\][[:space:]]*$/ { exit }
    { lines[++n] = $0 }
    END {
        while (n > 0 && lines[n] ~ /^[[:space:]]*$/) n--
        for (i = 1; i <= n; i++) print lines[i]
    }
' "$BOOT" > "$work/$IFACE.conf"

# Din fisierul aplicatiei acceptam numai peeri strict validati.
awk '
function fail(message) {
    print "Configuratie refuzata: " message > "/dev/stderr"
    failed = 1
    exit 1
}

function finish_peer() {
    if (in_peer && (pub_count != 1 || psk_count != 1 || ip_count != 1)) {
        fail("peer incomplet sau campuri duplicate")
    }
}

function valid_key(value) {
    return length(value) == 44 &&
           value ~ /^[A-Za-z0-9+\/]+=$/
}

{
    line = $0
    sub(/\r$/, "", line)
    sub(/^[[:space:]]+/, "", line)
    sub(/[[:space:]]+$/, "", line)

    if (line == "" || line ~ /^#/) {
        next
    }

    if (line == "[Peer]") {
        finish_peer()
        in_peer = 1
        pub_count = psk_count = ip_count = 0
        print "\n[Peer]"
        next
    }

    # Ignoram tot ce precede primul Peer din fisierul PHP.
    if (!in_peer) {
        next
    }

    pos = index(line, "=")
    if (!pos) {
        fail("linie nepermisa intr-un peer")
    }

    field = substr(line, 1, pos - 1)
    value = substr(line, pos + 1)

    sub(/[[:space:]]+$/, "", field)
    sub(/^[[:space:]]+/, "", value)

    if (field == "PublicKey") {
        if (++pub_count != 1 || !valid_key(value)) {
            fail("PublicKey invalid sau duplicat")
        }
        if (seen_key[value]++) {
            fail("aceeasi cheie publica apare la mai multi peeri")
        }
    } else if (field == "PresharedKey") {
        if (++psk_count != 1 || !valid_key(value)) {
            fail("PresharedKey invalid sau duplicat")
        }
    } else if (field == "AllowedIPs") {
        if (++ip_count != 1) {
            fail("AllowedIPs duplicat")
        }
        if (value !~ /^192\.168\.66\.[0-9]+\/32$/) {
            fail("AllowedIPs trebuie sa fie un singur IP din 192.168.66.0/24")
        }

        split(value, parts, /[.\/]/)
        octet = parts[4] + 0

        if (octet < 2 || octet > 254 ||
            value != sprintf("192.168.66.%d/32", octet)) {
            fail("adresa client nepermisa")
        }
        if (seen_ip[value]++) {
            fail("aceeasi adresa apare la mai multi peeri")
        }
    } else {
        fail("camp nepermis: " field)
    }

    print field " = " value
}

END {
    if (!failed) {
        finish_peer()
    }
}
' "$work/source.conf" >> "$work/$IFACE.conf"

wg-quick strip "$work/$IFACE.conf" > "$work/apply.conf"

if ip link show dev "$IFACE" >/dev/null 2>&1; then
    echo "Sincronizez peer-ii validati pentru $IFACE"
    wg syncconf "$IFACE" "$work/apply.conf"
else
    echo "Pornesc $IFACE din configuratia root si peer-ii validati"
    wg-quick up "$work/$IFACE.conf"
fi

# Persistam configuratia dupa aplicarea reusita.
persist_tmp=$(mktemp /etc/wireguard/wgui/.wghub.XXXXXX)
cat "$work/$IFACE.conf" > "$persist_tmp"
chmod 600 "$persist_tmp"
chown root:root "$persist_tmp"
mv -f -- "$persist_tmp" "$BOOT"
persist_tmp=""

echo "Configuratia pentru $IFACE a fost aplicata si salvata"
