#!/usr/bin/env bash
# wg_client_install — Device-side: instala wg0.conf en /etc/wireguard/, habilita
# systemd wg-quick@<iface>, verifica handshake con hub. Idempotente.
# Acepta config por path o stdin ("-").
# Exit 0 = éxito (installed o already-configured), 1 = error fatal.

wg_client_install() {
    local config_src="${1:--}"
    local iface="${2:-wg0}"
    local conf_dest="/etc/wireguard/${iface}.conf"
    local config_content="" hub_endpoint="" handshake_seen="false"

    _wg_ci_log() { echo "[wg_client_install] $*" >&2; }

    # ── Prereq: wg debe estar instalado ──────────────────────────────────────
    if ! command -v wg &>/dev/null; then
        _wg_ci_log "ERROR: 'wg' no encontrado. Ejecuta wg_install primero."
        return 1
    fi

    # ── Leer contenido del .conf ──────────────────────────────────────────────
    if [[ "${config_src}" == "-" ]]; then
        _wg_ci_log "Leyendo config desde stdin"
        config_content=$(cat) || { _wg_ci_log "ERROR: fallo al leer stdin"; return 1; }
    elif [[ -f "${config_src}" ]]; then
        _wg_ci_log "Leyendo config desde ${config_src}"
        config_content=$(cat "${config_src}") || { _wg_ci_log "ERROR: fallo al leer ${config_src}"; return 1; }
    else
        _wg_ci_log "ERROR: '${config_src}' no es un path existente ni '-' (stdin)"
        return 1
    fi

    if [[ -z "${config_content}" ]]; then
        _wg_ci_log "ERROR: contenido de config vacío"
        return 1
    fi

    # ── Extraer endpoint del hub para incluirlo en el JSON de salida ──────────
    hub_endpoint=$(printf '%s\n' "${config_content}" | grep -m1 '^Endpoint\s*=' | sed 's/.*=\s*//' | tr -d '[:space:]' || true)

    # ── Idempotencia: comparar con conf existente ─────────────────────────────
    if [[ -f "${conf_dest}" ]]; then
        local existing_content
        existing_content=$(sudo cat "${conf_dest}" 2>/dev/null || cat "${conf_dest}" 2>/dev/null || true)
        if [[ "${existing_content}" == "${config_content}" ]]; then
            _wg_ci_log "Configuración idéntica ya presente en ${conf_dest}; nada que hacer"
            printf '{"status":"already-configured","interface":"%s","hub_endpoint":"%s","handshake_seen":false}\n' \
                "${iface}" "${hub_endpoint}"
            return 0
        fi
        # Contenido difiere → backup + rewrite
        local backup="${conf_dest}.bak.$(date +%Y%m%d%H%M%S)"
        _wg_ci_log "Configuración existente difiere; backup → ${backup}"
        sudo cp "${conf_dest}" "${backup}" \
            || { _wg_ci_log "ERROR: no se pudo hacer backup de ${conf_dest}"; return 1; }
    fi

    # ── Crear directorio y escribir conf ─────────────────────────────────────
    sudo mkdir -p "/etc/wireguard" \
        || { _wg_ci_log "ERROR: no se pudo crear /etc/wireguard"; return 1; }

    printf '%s\n' "${config_content}" | sudo tee "${conf_dest}" >/dev/null \
        || { _wg_ci_log "ERROR: no se pudo escribir ${conf_dest}"; return 1; }

    sudo chmod 600 "${conf_dest}" \
        || { _wg_ci_log "WARN: no se pudo chmod 600 ${conf_dest}"; }

    _wg_ci_log "Config escrita en ${conf_dest} (chmod 600)"

    # ── Habilitar + arrancar systemd unit ─────────────────────────────────────
    if ! command -v systemctl &>/dev/null; then
        _wg_ci_log "WARN: systemctl no disponible."
        _wg_ci_log "  En WSL2 sin systemd: ejecuta 'sudo wg-quick up ${iface}' manualmente."
        _wg_ci_log "  Para autostart en WSL2: añade 'sudo wg-quick up ${iface}' a ~/.bashrc o usa WSL2 con systemd habilitado."
        printf '{"status":"installed-no-systemd","interface":"%s","hub_endpoint":"%s","handshake_seen":false}\n' \
            "${iface}" "${hub_endpoint}"
        return 0
    fi

    _wg_ci_log "Habilitando y arrancando wg-quick@${iface}"
    if ! sudo systemctl enable --now "wg-quick@${iface}" 2>&1 | tee /dev/stderr >&2; then
        _wg_ci_log "ERROR: systemctl enable --now wg-quick@${iface} falló."
        _wg_ci_log "  En WSL2: asegúrate de tener kernel >= 5.6 y systemd habilitado (/etc/wsl.conf: [boot] systemd=true)."
        _wg_ci_log "  Si NetworkManager gestiona ${iface}: añade 'unmanaged-devices=interface-name:${iface}' a /etc/NetworkManager/conf.d/99-wg.conf"
        return 1
    fi

    _wg_ci_log "wg-quick@${iface} habilitado y activo"

    # ── Esperar handshake (hasta 10 s) ────────────────────────────────────────
    local deadline=$(( $(date +%s) + 10 ))
    _wg_ci_log "Esperando handshake en ${iface} (timeout 10s)..."
    while [[ $(date +%s) -lt ${deadline} ]]; do
        local hs_output
        hs_output=$(sudo wg show "${iface}" latest-handshakes 2>/dev/null || true)
        # latest-handshakes devuelve "<pubkey>  <unix_ts>"; ts > 0 = handshake visto
        if printf '%s\n' "${hs_output}" | awk '{print $2}' | grep -qE '^[1-9][0-9]+$'; then
            handshake_seen="true"
            _wg_ci_log "Handshake confirmado en ${iface}"
            break
        fi
        sleep 1
    done

    if [[ "${handshake_seen}" == "false" ]]; then
        _wg_ci_log "WARN: timeout esperando handshake en ${iface}. La interfaz está activa pero el hub no ha respondido aún."
        _wg_ci_log "  Verifica: endpoint accesible, hub corriendo, claves correctas."
        printf '{"status":"installed-no-handshake","interface":"%s","hub_endpoint":"%s","handshake_seen":false}\n' \
            "${iface}" "${hub_endpoint}"
        return 0
    fi

    printf '{"status":"installed","interface":"%s","hub_endpoint":"%s","handshake_seen":true}\n' \
        "${iface}" "${hub_endpoint}"
    return 0
}
