#!/bin/bash
# ============================================================================
#  instalar-licencia.sh - Instalador OFICIAL de Astra + activacion
#
#  Un solo comando (se lo entregas al cliente con su codigo):
#
#     curl -fsSL https://astra.nexus.flashhub.net/instalar-licencia.sh \
#          | sudo bash -s -- --codigo ASTRA-XXXX-XXXX-XXXX
#
#  Opciones:
#     --codigo CODE   Codigo de activacion (obligatorio)
#     --puerto N      Puerto del panel (por defecto 8000)
#     --base URL      Origen del paquete (por defecto astra.nexus.flashhub.net)
#     --api URL       API de licencias (por defecto nexus.flashhub.net/licencia)
# ============================================================================
set -euo pipefail

BASE="${ASTRA_BASE:-https://astra.nexus.flashhub.net}"
API="${ASTRA_API:-https://nexus.flashhub.net/licencia}"
CODIGO=""
PUERTO="8000"

while [ $# -gt 0 ]; do
    case "$1" in
        --codigo) CODIGO="$2"; shift 2 ;;
        --puerto) PUERTO="$2"; shift 2 ;;
        --base)   BASE="$2"; shift 2 ;;
        --api)    API="$2"; shift 2 ;;
        *) echo "opcion desconocida: $1"; exit 1 ;;
    esac
done

[ "$(id -u)" = "0" ] || { echo "ERROR: ejecuta con sudo"; exit 1; }
[ -n "$CODIGO" ] || { echo "ERROR: falta --codigo ASTRA-XXXX-XXXX-XXXX"; exit 1; }
CODIGO="$(echo "$CODIGO" | tr '[:lower:]' '[:upper:]')"
command -v curl >/dev/null    || { echo "ERROR: falta curl"; exit 1; }
command -v python3 >/dev/null || { echo "ERROR: falta python3"; exit 1; }

echo "============================================================"
echo "  ASTRA - instalacion + activacion"
echo "  Codigo: $CODIGO     Panel: puerto $PUERTO"
echo "============================================================"

TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
cd "$TMP"

echo "[1/7] Descargando paquete de Astra..."
for f in astra astra.conf instalar-astra.sh desinstalar-astra.sh config-ejemplo.json \
         GUIA-DE-INSTALACION.md verificar.sh INFORME_AUDITORIA.md CAMBIOS.txt \
         CAMBIAR-PUERTO.md instalar-remoto.sh instalar-licencia.sh SHA256SUMS; do
    curl -fsSL -O "$BASE/$f"
done

echo "[2/7] Verificando integridad del paquete..."
sha256sum -c --status SHA256SUMS || { echo "[!] Paquete corrupto. Abortando."; exit 1; }

echo "[3/7] Instalando Astra..."
install -m 755 astra /usr/bin/astra
mkdir -p /etc/astra
[ -f /etc/astra/astra.conf ] || install -m 644 astra.conf /etc/astra/astra.conf

# Solo se bloquean los SERVIDORES DE LICENCIA (lo imprescindible).
# La ayuda oficial (help.cesbo.com -> astra.cesbo.com) queda accesible.
if ! grep -q "ls1.cesbo.com" /etc/hosts 2>/dev/null; then
    echo "127.0.0.1 ls1.cesbo.com ls2.cesbo.com ls3.cesbo.com" >> /etc/hosts
fi

echo "[4/7] Obteniendo material de activacion (codigo $CODIGO)..."
PAQUETE="$TMP/paquete.json"
curl -fsSL -X POST -H "Content-Type: application/json" \
     -d "{\"codigo\":\"$CODIGO\"}" "$API/api/v1/paquete" -o "$PAQUETE" || {
    echo "[!] El servidor rechazo el codigo. Verifica con tu proveedor."
    exit 1
}
python3 - "$PAQUETE" <<'PY'
import base64, json, sys
d = json.load(open(sys.argv[1]))
if not d.get("ok"):
    print("ERROR:", d.get("error")); raise SystemExit(1)
open("/usr/local/share/astra-guard.py", "wb").write(base64.b64decode(d["guard_py"]))
open("/usr/local/share/astra-ed25519.py", "wb").write(base64.b64decode(d["ed25519_py"]))
json.dump(d["leasekey"], open("/etc/astra/.leasekey", "w"), indent=2)
json.dump({"cliente": d.get("cliente"), "duracion": d.get("duracion"),
           "server": d.get("server"), "sha256_binario": d.get("sha256_binario")},
          open("/etc/astra/.activacion", "w"), indent=2)
print("      cliente:", d.get("cliente"), "| duracion:", d.get("duracion"))
PY

echo "[5/7] Comprobando que el binario es el oficial..."
SHA_LOCAL=$(sha256sum /usr/bin/astra | awk '{print $1}')
SHA_OFICIAL=$(python3 -c "import json;print(json.load(open('/etc/astra/.activacion')).get('sha256_binario') or '')")
if [ -n "$SHA_OFICIAL" ] && [ "$SHA_LOCAL" != "$SHA_OFICIAL" ]; then
    echo "[!] AVISO: el binario no coincide con el hash oficial ($SHA_LOCAL vs $SHA_OFICIAL)"
    echo "    La activacion lo reportara al servidor."
else
    echo "      -> binario verificado"
fi

echo "[6/7] Instalando guardian y servicios..."
mkdir -p /usr/local/lib/astra-guard /var/lib/astra-guard
install -m 644 /usr/local/share/astra-guard.py /usr/local/lib/astra-guard/guard.py
install -m 644 /usr/local/share/astra-ed25519.py /usr/local/lib/astra-guard/ed25519.py
chmod 600 /etc/astra/.leasekey
cat > /usr/bin/astra-guard <<'EOF'
#!/bin/sh
exec /usr/bin/python3 /usr/local/lib/astra-guard/guard.py "$@"
EOF
chmod 755 /usr/bin/astra-guard

python3 - "$API" "$CODIGO" <<'PY'
import json, sys
api, codigo = sys.argv[1], sys.argv[2]
cfg = {
    "server": api,
    "lease_path": "/etc/astra/.lease",
    "license_path": "/etc/astra/.lic",
    "pubkey_path": "/etc/astra/.server.pub",
    "secret_path": "/etc/astra/.leasekey",
    "state_path": "/var/lib/astra-guard/state.json",
    "binario_path": "/usr/bin/astra",
    "check_interval_min": 720,
    "http_timeout": 20,
    "insecure_tls": False,
    "auto_start_astra": True,
    "codigo": codigo,
}
json.dump(cfg, open("/etc/astra/guard.json", "w"), indent=2)
PY
chmod 600 /etc/astra/guard.json

cat > /etc/systemd/system/astra-guard.service <<'EOF'
[Unit]
Description=Astra Guard (activacion / vigencia)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/astra-guard -c /etc/astra/guard.json daemon
Restart=always
RestartSec=15
User=root

[Install]
WantedBy=multi-user.target
EOF

cat > /etc/systemd/system/astra.service <<EOF
[Unit]
Description=Astra Media Server
After=network.target astra-guard.service
Requires=astra-guard.service
ConditionPathExists=/etc/astra/.lease

[Service]
Type=simple
ExecStartPre=/usr/bin/astra-guard check
ExecStartPre=/bin/sleep 8
ExecStart=/usr/bin/astra -c /etc/astra/astra.conf -p $PUERTO
Restart=always
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable astra-guard.service >/dev/null 2>&1 || true
systemctl enable astra.service >/dev/null 2>&1 || true
systemctl restart astra-guard.service

echo "[7/7] Vinculando el equipo..."
for i in $(seq 1 10); do
    sleep 3
    if /usr/bin/astra-guard -c /etc/astra/guard.json check >/dev/null 2>&1; then break; fi
    /usr/bin/astra-guard -c /etc/astra/guard.json enroll >/dev/null 2>&1 || true
done

if /usr/bin/astra-guard -c /etc/astra/guard.json check >/dev/null 2>&1; then
    systemctl start astra.service
    sleep 3
    echo
    echo "============================================================"
    echo "  INSTALADO Y ACTIVADO"
    echo "============================================================"
    /usr/bin/astra-guard -c /etc/astra/guard.json status
    IP=$(hostname -I 2>/dev/null | awk '{print $1}')
    echo
    echo "  Panel Astra : http://$IP:$PUERTO   (admin / admin)"
    echo "  Vigencia    : en el panel -> Settings -> License"
    echo "============================================================"
else
    echo
    echo "AVISO: el equipo no pudo vincularse todavia."
    echo "Revisa: journalctl -u astra-guard -n 40"
    echo "Si el codigo ya fue usado en OTRO equipo, pide uno nuevo."
fi
