#!/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
# ============================================================================
set -euo pipefail

# ─── 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"; read -r r; echo "${r:-$default}"; }
step() { echo; echo "${BOLD}${BLUE}━━━ $* ━━━${RESET}"; }

# ─── Parse flags ────────────────────────────────────────────────────────────
UNATTENDED=0
ACME_DOMAIN=""
ACME_EMAIL=""
UPSTREAMS="1.1.1.1:53,8.8.8.8:53,9.9.9.9: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)"

. /etc/os-release 2>/dev/null || true
DISTRO="${ID:-unknown}"
case "$DISTRO" in
  debian|ubuntu)
    PKG_INSTALL="DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends"
    PKG_UPDATE="apt-get update -qq"
    ;;
  rhel|centos|rocky|almalinux|fedora)
    PKG_INSTALL="dnf install -y"
    PKG_UPDATE="dnf check-update || true"
    ;;
  alpine)
    PKG_INSTALL="apk add --no-cache"
    PKG_UPDATE="apk update"
    ;;
  *) fail "distro $DISTRO ainda não suportada · pede no suporte" ;;
esac
ok "distro: $DISTRO"

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"
id dnssuper >/dev/null 2>&1 || useradd -r -s /bin/false -d /opt/dnssuper dnssuper
mkdir -p /opt/dnssuper/data /opt/dnssuper/certs /opt/dnssuper/logs /opt/dnssuper/backups
chown -R dnssuper:dnssuper /opt/dnssuper
ok "/opt/dnssuper/ criado"

# ─── 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
User=dnssuper
Group=dnssuper
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
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
