#!/usr/bin/env bash
# ============================================================================
# IspFull-DnsSuper · Installer
# ----------------------------------------------------------------------------
# Uso interativo (recomendado primeira vez):
#   curl -fsSL https://get.ispfull.com.br | sudo bash
#
# Uso automatizado (CI/CD/scripts):
#   curl -fsSL https://get.ispfull.com.br | sudo bash -s -- \
#       --unattended \
#       --acme-domain dns.suaempresa.com.br \
#       --acme-email admin@suaempresa.com.br
#
# Flags:
#   --unattended            sem prompts, usa defaults
#   --acme-domain DOM       habilita ACME LE pro domínio
#   --acme-email EMAIL      email pra registro ACME (obrigatório se --acme-domain)
#   --upstream LISTA        resolvers upstream CSV (default 1.1.1.1:53,8.8.8.8:53,9.9.9.9:53)
#   --bind-ip IP            força bind num IP específico
#   --version VER           instala versão específica (default latest)
#   --channel stable|beta   canal (default stable)
#   --no-systemd            só instala binário, sem service
#   --help                  mostra esta ajuda
#
# Requisitos: Debian 12+ (bookworm) ou Ubuntu 22.04+ LTS · amd64 · root/sudo
# ============================================================================
set -euo pipefail

# Garantir /usr/sbin e /sbin no PATH (sudo via pipe às vezes restringe — useradd/adduser vivem lá)
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"

# ─── Cores ──────────────────────────────────────────────────────────────────
if [ -t 1 ] && command -v tput >/dev/null 2>&1; then
  BOLD=$(tput bold); RED=$(tput setaf 1); GREEN=$(tput setaf 2)
  YELLOW=$(tput setaf 3); BLUE=$(tput setaf 4); CYAN=$(tput setaf 6)
  GRAY=$(tput setaf 8); RESET=$(tput sgr0)
else
  BOLD=""; RED=""; GREEN=""; YELLOW=""; BLUE=""; CYAN=""; GRAY=""; RESET=""
fi

logo() {
  cat <<EOF
${CYAN}${BOLD}
   ____            ____
  |  _ \\ _ __  ___/ ___| _   _ _ __   ___ _ __
  | | | | '_ \\/ __\\___ \\| | | | '_ \\ / _ \\ '__|
  | |_| | | | \\__ \\___) | |_| | |_) |  __/ |
  |____/|_| |_|___/____/ \\__,_| .__/ \\___|_|
                              |_|
${RESET}${GRAY}  IspFull-DnsSuper · DNS authoritative + recursive em Go${RESET}
${GRAY}  https://gestorispfull.ispfull.com.br${RESET}

EOF
}

ok()   { echo "${GREEN}✔${RESET} $*"; }
info() { echo "${BLUE}ℹ${RESET} $*"; }
warn() { echo "${YELLOW}⚠${RESET} $*"; }
fail() { echo "${RED}✘${RESET} $*"; exit 1; }
ask()  {
  local p="$1" default="${2:-}"; local r=""
  printf "${CYAN}?${RESET} %s ${GRAY}[%s]${RESET}: " "$p" "$default" >&2
  # CRÍTICO: ler de /dev/tty (terminal real) e não de stdin —
  # quando o script vem via curl|bash, stdin é o pipe do script
  # e um read normal consome as PRÓXIMAS LINHAS DO PRÓPRIO SCRIPT.
  if [ -r /dev/tty ]; then
    read -r r </dev/tty || r=""
  fi
  echo "${r:-$default}"
}
step() { echo; echo "${BOLD}${BLUE}━━━ $* ━━━${RESET}"; }

# ─── Parse flags ────────────────────────────────────────────────────────────
UNATTENDED=0
ACME_DOMAIN=""
ACME_EMAIL=""
UPSTREAMS="1.1.1.1:53,[2606:4700:4700::1111]:53,8.8.8.8:53,[2606:4700:4700::1001]:53,9.9.9.9:53,[2620:fe::fe]:53"
BIND_IP=""
INSTALL_VERSION="latest"
CHANNEL="stable"
NO_SYSTEMD=0

while [ $# -gt 0 ]; do
  case "$1" in
    --unattended)      UNATTENDED=1 ;;
    --acme-domain)     ACME_DOMAIN="$2"; shift ;;
    --acme-email)      ACME_EMAIL="$2";  shift ;;
    --upstream)        UPSTREAMS="$2";   shift ;;
    --bind-ip)         BIND_IP="$2";     shift ;;
    --version)         INSTALL_VERSION="$2"; shift ;;
    --channel)         CHANNEL="$2";     shift ;;
    --no-systemd)      NO_SYSTEMD=1 ;;
    --help|-h)         sed -n '2,30p' "$0"; exit 0 ;;
    *) fail "flag desconhecida: $1" ;;
  esac
  shift
done

# ─── Pre-flight ─────────────────────────────────────────────────────────────
logo
step "Pre-flight checks"

[ "$(id -u)" -eq 0 ] || fail "rode como root (sudo)"

# ─── Distro suportada: SOMENTE Debian 12+ e Ubuntu 22.04+ ───────────────────
# Política oficial: o DnsSuper só é homologado/suportado em Debian e Ubuntu.
# Outras distros (RHEL/Rocky/Alma/Fedora/Alpine/Arch) ficam de fora de propósito —
# o binário é Go estático e até rodaria, mas suporte vira inviável. Travamos cedo,
# antes de qualquer download, pra dar mensagem clara em vez de erro genérico depois.
. /etc/os-release 2>/dev/null || true
DISTRO="${ID:-unknown}"
DISTRO_VER="${VERSION_ID:-0}"      # ex.: "12" (debian) ou "22.04" (ubuntu)
DISTRO_MAJOR="${DISTRO_VER%%.*}"   # só o major pra comparação numérica
case "$DISTRO" in
  debian)
    [ "${DISTRO_MAJOR:-0}" -ge 12 ] 2>/dev/null \
      || fail "Debian ${DISTRO_VER} não suportado · precisa Debian 12 (bookworm) ou superior"
    ;;
  ubuntu)
    [ "${DISTRO_MAJOR:-0}" -ge 22 ] 2>/dev/null \
      || fail "Ubuntu ${DISTRO_VER} não suportado · precisa Ubuntu 22.04 LTS ou superior"
    ;;
  *)
    fail "distro '${DISTRO}' não suportada · o DnsSuper só roda em Debian 12+ ou Ubuntu 22.04+"
    ;;
esac
# Daqui pra frente é garantidamente apt-based (Debian/Ubuntu).
PKG_INSTALL="DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends"
PKG_UPDATE="apt-get update -qq"
ok "distro: $DISTRO $DISTRO_VER"

ARCH=$(uname -m)
case "$ARCH" in
  x86_64|amd64) ARCH=amd64 ;;
  aarch64|arm64) ARCH=arm64 ;;
  *) fail "arch $ARCH não suportada (precisa amd64 ou arm64)" ;;
esac
ok "arquitetura: $ARCH"

# Porta 53 livre?
if ss -tlnp 2>/dev/null | grep -qE ':53\s'; then
  warn "porta 53 já em uso. Listeners atuais:"
  ss -tlnp | grep ':53' | head -3
  warn "se for systemd-resolved, vamos desabilitar — DnsSuper precisa da 53"
  if [ "$UNATTENDED" = "0" ]; then
    c=$(ask "Desabilitar systemd-resolved agora?" "s")
    [ "$c" = "s" ] || fail "cancelado"
  fi
  systemctl disable --now systemd-resolved 2>/dev/null || true
  if [ -L /etc/resolv.conf ]; then
    rm /etc/resolv.conf
    cat > /etc/resolv.conf <<EOF
nameserver 127.0.0.1
nameserver 1.1.1.1
EOF
  fi
  ok "systemd-resolved desabilitado"
fi

step "Instalando dependências"
eval $PKG_UPDATE
eval $PKG_INSTALL ca-certificates curl wget dnsutils libcap2-bin >/dev/null 2>&1 || warn "algumas deps não instalaram (ok se já tem)"
ok "deps prontas"

# ─── Wizard interativo ─────────────────────────────────────────────────────
if [ "$UNATTENDED" = "0" ]; then
  step "Configuração (Enter pra aceitar defaults)"
  if [ -z "$ACME_DOMAIN" ]; then
    ACME_DOMAIN=$(ask "Domínio pro painel (ex: dns.empresa.com.br · vazio = só HTTP local)" "")
  fi
  if [ -n "$ACME_DOMAIN" ] && [ -z "$ACME_EMAIL" ]; then
    ACME_EMAIL=$(ask "Email pra registro ACME Let's Encrypt" "")
  fi
  UPSTREAMS=$(ask "Resolvers upstream (CSV)" "$UPSTREAMS")
  if [ -z "$BIND_IP" ]; then
    SUGGEST=$(ip -4 addr show scope global | awk '/inet / {print $2}' | head -1 | cut -d/ -f1)
    BIND_IP=$(ask "Bind IP (vazio = todos)" "$SUGGEST")
  fi
fi

# ─── Diretórios + user ─────────────────────────────────────────────────────
step "Criando estrutura"
DNSUSER=dnssuper
DNSGROUP=dnssuper
if ! getent passwd dnssuper >/dev/null 2>&1; then
  # tenta adduser (Debian-friendly) → useradd (path absoluto) → fallback root
  if command -v adduser >/dev/null 2>&1; then
    adduser --system --group --no-create-home --home /opt/dnssuper --shell /usr/sbin/nologin dnssuper >/dev/null 2>&1 || true
  fi
  if ! getent passwd dnssuper >/dev/null 2>&1; then
    /usr/sbin/useradd -r -s /usr/sbin/nologin -d /opt/dnssuper dnssuper >/dev/null 2>&1 || true
  fi
  if ! getent passwd dnssuper >/dev/null 2>&1; then
    warn "não consegui criar user 'dnssuper' (useradd/adduser falharam) · usando root"
    DNSUSER=root
    DNSGROUP=root
  fi
fi
mkdir -p /opt/dnssuper/data /opt/dnssuper/certs /opt/dnssuper/logs /opt/dnssuper/backups
chown -R "$DNSUSER:$DNSGROUP" /opt/dnssuper
ok "/opt/dnssuper/ criado (owner: $DNSUSER)"

# ─── Download binário ──────────────────────────────────────────────────────
step "Baixando binário"
DL_URL="https://gestorispfull.ispfull.com.br/dl/dnssuper-${ARCH}"
[ "$INSTALL_VERSION" != "latest" ] && DL_URL="${DL_URL}-${INSTALL_VERSION}"
TMP=$(mktemp -d)
trap "rm -rf $TMP" EXIT
if ! curl -fsSL "$DL_URL" -o "$TMP/dnssuper"; then
  warn "download remoto falhou — tentando local /opt/dnssuper/dnssuper-bundle"
  if [ -f /opt/dnssuper/dnssuper-bundle ]; then
    cp /opt/dnssuper/dnssuper-bundle "$TMP/dnssuper"
  else
    fail "não consegui baixar nem achar binário local · checa conexão"
  fi
fi
chmod +x "$TMP/dnssuper"
install -m 755 "$TMP/dnssuper" /usr/local/sbin/dnssuper
ok "/usr/local/sbin/dnssuper instalado ($(du -h /usr/local/sbin/dnssuper | cut -f1))"

setcap 'cap_net_bind_service=+ep' /usr/local/sbin/dnssuper 2>/dev/null || warn "setcap falhou (precisa libcap2-bin)"

# ─── Systemd unit ──────────────────────────────────────────────────────────
if [ "$NO_SYSTEMD" = "0" ]; then
  step "Criando systemd unit"
  EXTRA_FLAGS=""
  [ -n "$BIND_IP" ] && EXTRA_FLAGS="$EXTRA_FLAGS -dns ${BIND_IP}:53"
  [ -n "$ACME_DOMAIN" ] && EXTRA_FLAGS="$EXTRA_FLAGS -acme-domain $ACME_DOMAIN -acme-email $ACME_EMAIL"

  cat > /etc/systemd/system/dnssuper.service <<EOF
[Unit]
Description=IspFull-DnsSuper · DNS authoritative + recursive
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
# Roda como root porque o managed-ips precisa adicionar/remover endereços
# na NIC via netlink (RTNETLINK) — caps sandboxed (NoNewPrivileges + boundingset
# restrito) bloqueiam isso mesmo com User=dnssuper + setcap cap_net_admin.
User=root
Group=root
ExecStart=/usr/local/sbin/dnssuper \\
  -http :9090 \\
  -db /opt/dnssuper/data/dnssuper.db \\
  -upstreams $UPSTREAMS \\
  $EXTRA_FLAGS
Restart=always
RestartSec=3
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF
  systemctl daemon-reload
  systemctl enable dnssuper >/dev/null 2>&1
  systemctl restart dnssuper
  ok "systemd unit ativo · journalctl -u dnssuper -f pra logs"
fi

# ─── Smoke test ────────────────────────────────────────────────────────────
step "Smoke test"
sleep 3
HEALTHY=1
for d in google.com cloudflare.com; do
  if R=$(dig +short +time=2 +tries=1 @127.0.0.1 "$d" 2>/dev/null | head -1) && [ -n "$R" ]; then
    ok "dig $d → $R"
  else
    warn "dig $d falhou"
    HEALTHY=0
  fi
done
if curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9090/ | grep -q 200; then
  ok "painel HTTP 9090 respondendo"
else
  warn "painel 9090 não respondeu"
  HEALTHY=0
fi

# ─── Resumo final ──────────────────────────────────────────────────────────
echo
echo "${BOLD}${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
if [ "$HEALTHY" = "1" ]; then
  echo "${BOLD}${GREEN}  ✔ INSTALAÇÃO COMPLETA${RESET}"
else
  echo "${BOLD}${YELLOW}  ⚠ INSTALAÇÃO COM AVISOS — checa logs${RESET}"
fi
echo "${BOLD}${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo
IP_LOCAL=$(ip -4 addr show scope global 2>/dev/null | awk '/inet / {print $2}' | head -1 | cut -d/ -f1)
echo "  ${BOLD}Painel admin:${RESET}    http://${IP_LOCAL:-127.0.0.1}:9090"
echo "  ${BOLD}Login default:${RESET}   ${YELLOW}admin / sistema123${RESET}  ${RED}(TROQUE AGORA!)${RESET}"
echo "  ${BOLD}Documentação:${RESET}    http://${IP_LOCAL:-127.0.0.1}:9090/docs"
echo "  ${BOLD}Logs:${RESET}            journalctl -u dnssuper -f"
echo "  ${BOLD}Status:${RESET}          systemctl status dnssuper"
echo
echo "  ${GRAY}DNS rodando em :53 (UDP+TCP) · painel em :9090 · DoT :853 · DoH :443${RESET}"
echo
echo "  ${BOLD}Próximo passo:${RESET} ative sua licença em ${CYAN}Painel → 🔑 Licença & Update${RESET}"
echo "  (você tem ${YELLOW}7 dias trial${RESET} grátis pra avaliar antes)"
echo
