#!/usr/bin/env bash
set -Eeuo pipefail

CADU_BASE_URL="${CADU_BASE_URL:-https://cadu.6201170.xyz}"
NYA_INSTALL_URL="${NYA_INSTALL_URL:-https://dl.nyafw.com/download/nyanpass-install.sh}"
BOOTSTRAP_MARKER="${BOOTSTRAP_MARKER:-/var/lib/cadu-bootstrap/completed}"
PRESET_CF_TOKEN="${PRESET_CF_TOKEN:-RCfXlAfTjz7FpVcbchoazTx2aP_rjJBrlhHmW4Vt}"
PRESET_ALIYUN_KEY_ID="${PRESET_ALIYUN_KEY_ID:-LTAI5tF7ZcJV2viXy2KVyuLJ}"
PRESET_ALIYUN_KEY_SECRET="${PRESET_ALIYUN_KEY_SECRET:-OGUgexqCID3FSjbO4DUGHfAuZpActB}"
PRESET_ALIYUN_DOMAIN="${PRESET_ALIYUN_DOMAIN:-5tencent.asia}"
PRESET_NYA_TOKEN="${PRESET_NYA_TOKEN:-164eec5a-5434-4ef3-8dfa-df767f9e0a06}"
PRESET_NYA_URL="${PRESET_NYA_URL:-https://2nps.698986.xyz}"

DDNS_PROVIDER="aliyun"
DDNS_PROVIDER_SET=0
SKIP_CADU=0
SKIP_DDNS=0
ALIYUN_KEY_ID=""
ALIYUN_KEY_SECRET=""
ALIYUN_HOST=""
CF_TOKEN=""
CF_ZONE_ID=""
CF_HOST=""
AWS_TOKEN=""
AWS_SHARE_ID=""
AWS_REGION=""
SKIP_IP_ROTATE=0
SKIP_NYA_DNS=0
SKIP_NYA=0
SKIP_OPTIMIZE=0
SELECT_SERVICES=0
FORCE_RUN=0
NYA_TOKEN=""
NYA_URL=""
NYA_SERVICE_NAME=""
NEZHA_SERVER=""
NEZHA_TLS="false"
NEZHA_CLIENT_SECRET=""
NEZHA_UUID=""
SKIP_NEZHA=1
NEZHA_EXPLICIT_SKIP=0
NEZHA_MENU_SELECTED=0
NEZHA_DEFAULTS_APPLIED=0
PRESET_HOST=""

usage() {
  cat <<'USAGE'
Usage: start.sh [options]

Required options:
  Aliyun options (for aliyun/both):
  --aliyun-key-id ID
  --aliyun-key-secret SECRET
  --aliyun-host RR.DOMAIN
  Cloudflare options (for cloudflare/both):
  --cf-token TOKEN
  --cf-host RR.DOMAIN
  --aws-token TOKEN              Required unless --skip-ip-rotate is used
  --aws-share-id ID             Auto-detected on EC2 when omitted
  --nya-token TOKEN
  --nya-url URL

Optional:
  --host NAME                   Use a built-in managed-host preset
  --provider aliyun|cloudflare|both
                                  Defaults to aliyun
  --skip-cadu                    Do not install CADU
  --skip-ddns                    Do not run CADU DDNS; disable it if present
  --cf-zone-id ID               Auto-detected when omitted (requires Zone Read)
  --aws-region REGION           Auto-detected when omitted
  --skip-ip-rotate              Do not run CADU IP rotation; disable it if present
  --skip-nya-dns                Do not configure local dnsmasq for NyanPass
  --skip-nya                    Do not install NyanPass; disable it if present
  --skip-optimize               Do not run CADU test-server optimization
  --enable-nezha               Install Nezha Agent (off by default in parameter mode)
  --skip-nezha                 Do not install Nezha Agent
  --nezha-server HOST:PORT
  --nezha-tls true|false        Defaults to false
  --nezha-client-secret SECRET
  --nezha-uuid UUID
  --select-services             Show an interactive service selection menu
  --force                       Run even when the bootstrap marker exists
  --nya-service-name NAME       Defaults to a persisted random name

The bootstrap installs CADU, runs test-server optimization, installs DDNS and
aws.sb IP rotation, then installs the NyanPass node client.
USAGE
}

die() {
  printf 'ERROR: %s\n' "$*" >&2
  exit 1
}

need_value() {
  if [ "$#" -lt 2 ] || [ -z "$2" ]; then
    die "$1 requires a value"
  fi
}

apply_nezha_host_defaults() {
  local host_key

  [ "$NEZHA_EXPLICIT_SKIP" -ne 1 ] || return 0
  host_key="$PRESET_HOST"
  [ -n "$host_key" ] || host_key="${CF_HOST%%.*}"
  [ -n "$host_key" ] || host_key="${ALIYUN_HOST%%.*}"
  case "$host_key" in
    y8q2lr)
      NEZHA_UUID="${NEZHA_UUID:-a67ff8d8-e62a-9292-bef1-c279c2d506dc}"
      ;;
    hssk002)
      NEZHA_UUID="${NEZHA_UUID:-f4f68bb4-b730-8ae2-f254-84a834287424}"
      ;;
    hssk006)
      NEZHA_UUID="${NEZHA_UUID:-db4a18db-ccd9-e5e1-f363-4c1ae066423d}"
      ;;
    p5r8cj)
      NEZHA_UUID="${NEZHA_UUID:-9c7e5e27-4e0c-0359-c5e0-5daad24079ab}"
      ;;
    b9m2vp)
      NEZHA_UUID="${NEZHA_UUID:-dda86544-8955-adeb-2ac4-1b152cba54f9}"
      ;;
    l9p4xd)
      NEZHA_UUID="${NEZHA_UUID:-994e15af-eb59-bc9a-6927-c0b7ae1b85b0}"
      ;;
    g4v9rc)
      NEZHA_UUID="${NEZHA_UUID:-b54f97c5-bd45-ff94-e1c5-6163e62bec53}"
      ;;
    n4x8wp)
      NEZHA_UUID="${NEZHA_UUID:-a590fc9c-2f52-abfa-d876-7860dff41c84}"
      ;;
    *)
      return 0
      ;;
  esac
  NEZHA_SERVER="${NEZHA_SERVER:-lskwmw.digitalage.services:28902}"
  NEZHA_TLS="${NEZHA_TLS:-false}"
  NEZHA_CLIENT_SECRET="${NEZHA_CLIENT_SECRET:-wrqQmDWnb9uXoIuP8ICFrj0poCIWtlvE}"
  SKIP_NEZHA=0
  NEZHA_DEFAULTS_APPLIED=1
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --host) need_value "$@"; PRESET_HOST="${2,,}"; shift 2 ;;
    --provider) need_value "$@"; DDNS_PROVIDER="$2"; DDNS_PROVIDER_SET=1; shift 2 ;;
    --skip-cadu) SKIP_CADU=1; shift ;;
    --skip-ddns) SKIP_DDNS=1; shift ;;
    --aliyun-key-id) need_value "$@"; ALIYUN_KEY_ID="$2"; shift 2 ;;
    --aliyun-key-secret) need_value "$@"; ALIYUN_KEY_SECRET="$2"; shift 2 ;;
    --aliyun-host) need_value "$@"; ALIYUN_HOST="$2"; shift 2 ;;
    --cf-token) need_value "$@"; CF_TOKEN="$2"; shift 2 ;;
    --cf-zone-id) need_value "$@"; CF_ZONE_ID="$2"; shift 2 ;;
    --cf-host) need_value "$@"; CF_HOST="$2"; shift 2 ;;
    --aws-token) need_value "$@"; AWS_TOKEN="$2"; shift 2 ;;
    --aws-share-id) need_value "$@"; AWS_SHARE_ID="$2"; shift 2 ;;
    --aws-region) need_value "$@"; AWS_REGION="$2"; shift 2 ;;
    --skip-ip-rotate) SKIP_IP_ROTATE=1; shift ;;
    --skip-nya-dns) SKIP_NYA_DNS=1; shift ;;
    --skip-nya) SKIP_NYA=1; shift ;;
    --skip-optimize) SKIP_OPTIMIZE=1; shift ;;
    --enable-nezha) SKIP_NEZHA=0; shift ;;
    --skip-nezha) SKIP_NEZHA=1; NEZHA_EXPLICIT_SKIP=1; shift ;;
    --nezha-server) need_value "$@"; NEZHA_SERVER="$2"; SKIP_NEZHA=0; shift 2 ;;
    --nezha-tls) need_value "$@"; NEZHA_TLS="$2"; SKIP_NEZHA=0; shift 2 ;;
    --nezha-client-secret) need_value "$@"; NEZHA_CLIENT_SECRET="$2"; SKIP_NEZHA=0; shift 2 ;;
    --nezha-uuid) need_value "$@"; NEZHA_UUID="$2"; SKIP_NEZHA=0; shift 2 ;;
    --select-services) SELECT_SERVICES=1; shift ;;
    --force) FORCE_RUN=1; shift ;;
    --nya-token) need_value "$@"; NYA_TOKEN="$2"; shift 2 ;;
    --nya-url) need_value "$@"; NYA_URL="$2"; shift 2 ;;
    --nya-service-name) need_value "$@"; NYA_SERVICE_NAME="$2"; shift 2 ;;
    -h|--help) usage; exit 0 ;;
    *) die "unknown option: $1" ;;
  esac
done

if [ -n "$PRESET_HOST" ]; then
  case "$PRESET_HOST" in
    y8q2lr|p5r8cj|b9m2vp|l9p4xd|g4v9rc|n4x8wp|hssk002|hssk006) ;;
    *) die "--host is not a managed host name" ;;
  esac
  if [ "$DDNS_PROVIDER_SET" -ne 1 ]; then
    if [ "$PRESET_HOST" = "hssk006" ]; then
      DDNS_PROVIDER="cloudflare"
    else
      DDNS_PROVIDER="aliyun"
    fi
  fi
  if [ "$DDNS_PROVIDER" = "aliyun" ] || [ "$DDNS_PROVIDER" = "both" ]; then
    ALIYUN_KEY_ID="${ALIYUN_KEY_ID:-$PRESET_ALIYUN_KEY_ID}"
    ALIYUN_KEY_SECRET="${ALIYUN_KEY_SECRET:-$PRESET_ALIYUN_KEY_SECRET}"
    ALIYUN_HOST="${ALIYUN_HOST:-${PRESET_HOST}.${PRESET_ALIYUN_DOMAIN}}"
  fi
  if [ "$DDNS_PROVIDER" = "cloudflare" ] || [ "$DDNS_PROVIDER" = "both" ]; then
    CF_TOKEN="${CF_TOKEN:-$PRESET_CF_TOKEN}"
    CF_HOST="${CF_HOST:-${PRESET_HOST}.guccen.top}"
  fi
  NYA_TOKEN="${NYA_TOKEN:-$PRESET_NYA_TOKEN}"
  NYA_URL="${NYA_URL:-$PRESET_NYA_URL}"
  [ -n "$AWS_TOKEN" ] || SKIP_IP_ROTATE=1
fi

if [ "$SELECT_SERVICES" -ne 1 ]; then
  apply_nezha_host_defaults
fi

if [ -f "$BOOTSTRAP_MARKER" ] && [ "$FORCE_RUN" -ne 1 ] && [ "$SELECT_SERVICES" -ne 1 ]; then
  printf 'CADU bootstrap already completed: %s\n' "$BOOTSTRAP_MARKER"
  printf 'Use --select-services to choose additional tasks, or --force to rerun parameterized tasks.\n'
  exit 0
fi

if [ "$SELECT_SERVICES" -eq 1 ]; then
  SKIP_CADU=1
  SKIP_DDNS=1
  SKIP_NYA_DNS=1
  SKIP_NYA=1
  SKIP_IP_ROTATE=1
  SKIP_OPTIMIZE=1
  SKIP_NEZHA=1
  cat <<'MENU'
============================================================
CADU 开机任务选择
============================================================
1. 安装 CADU 主程序                         [可跳过]
2. 安装并启动 DDNS                         [可跳过]
3. 安装并验证 NyanPass 本地 DNS            [可跳过]
4. 安装并启动 NyanPass                     [可跳过]
5. 安装 aws.sb 自动换 IP                   [可跳过]
6. 执行测试服务器一键优化                  [可跳过，最后执行]
7. 安装并启动哪吒 Agent                    [可跳过]
------------------------------------------------------------
输入要执行的服务编号，支持空格或逗号分隔，例如：2 5
直接回车或输入 0 表示选择全部。
MENU
  printf '选择：'
  IFS= read -r service_selection || die "无法读取服务选择"
  service_selection="${service_selection//,/ }"
  read -r -a selected_services <<<"$service_selection"
  if [ "${#selected_services[@]}" -eq 0 ] || [ "${selected_services[0]:-}" = "0" ]; then
    selected_services=(1 2 3 4 5 6 7)
  fi
  for selection in "${selected_services[@]}"; do
    case "$selection" in
      1|cadu) SKIP_CADU=0 ;;
      2|ddns) SKIP_DDNS=0 ;;
      3|nya-dns|nya_dns) SKIP_NYA_DNS=0 ;;
      4|nya) SKIP_NYA=0 ;;
      5|ip-rotate|ip_rotate) SKIP_IP_ROTATE=0 ;;
      6|optimize) SKIP_OPTIMIZE=0 ;;
      7|nezha) SKIP_NEZHA=0; NEZHA_MENU_SELECTED=1 ;;
      *) die "无法识别的服务选择：$selection" ;;
    esac
  done
  if [ "$SKIP_DDNS" -ne 1 ] || [ "$SKIP_IP_ROTATE" -ne 1 ] || [ "$SKIP_OPTIMIZE" -ne 1 ]; then
    SKIP_CADU=0
  fi
  printf '选择结果：CADU=%s，DDNS=%s，NyanPass DNS=%s，NyanPass=%s，自动换 IP=%s，优化=%s，哪吒=%s\n' \
    "$([ "$SKIP_CADU" -eq 1 ] && printf '跳过' || printf '执行')" \
    "$([ "$SKIP_DDNS" -eq 1 ] && printf '跳过' || printf '执行')" \
    "$([ "$SKIP_NYA_DNS" -eq 1 ] && printf '跳过' || printf '执行')" \
    "$([ "$SKIP_NYA" -eq 1 ] && printf '跳过' || printf '执行')" \
    "$([ "$SKIP_IP_ROTATE" -eq 1 ] && printf '跳过' || printf '执行')" \
    "$([ "$SKIP_OPTIMIZE" -eq 1 ] && printf '跳过' || printf '执行')" \
    "$([ "$SKIP_NEZHA" -eq 1 ] && printf '跳过' || printf '执行')"
fi

prompt_missing() {
  local variable="$1"
  local prompt="$2"
  local secret="${3:-0}"
  local value="${!variable}"

  [ -z "$value" ] || return 0
  if [ "$secret" -eq 1 ]; then
    read -r -s -p "$prompt" value || die "无法读取 $variable"
    printf '\n'
  else
    read -r -p "$prompt" value || die "无法读取 $variable"
  fi
  [ -n "$value" ] || die "$variable 不能为空"
  printf -v "$variable" '%s' "$value"
}

if [ "$SELECT_SERVICES" -eq 1 ]; then
  if [ "$SKIP_DDNS" -ne 1 ]; then
    if [ "$DDNS_PROVIDER_SET" -ne 1 ]; then
      read -r -p 'DDNS 服务商 [aliyun/cloudflare/both，默认 both]：' provider_input ||
        die "无法读取 DDNS 服务商"
      DDNS_PROVIDER="${provider_input:-both}"
    fi
    if [ "$DDNS_PROVIDER" = "aliyun" ] || [ "$DDNS_PROVIDER" = "both" ]; then
      prompt_missing ALIYUN_KEY_ID '阿里云 AccessKey ID：'
      prompt_missing ALIYUN_KEY_SECRET '阿里云 AccessKey Secret（隐藏输入）：' 1
      prompt_missing ALIYUN_HOST '阿里云 DDNS 完整域名：'
    fi
    if [ "$DDNS_PROVIDER" = "cloudflare" ] || [ "$DDNS_PROVIDER" = "both" ]; then
      prompt_missing CF_TOKEN 'Cloudflare API Token（隐藏输入）：' 1
      prompt_missing CF_HOST 'Cloudflare DDNS 完整域名：'
      if [ -z "$CF_ZONE_ID" ]; then
        read -r -p 'Cloudflare Zone ID（可留空自动查询）：' CF_ZONE_ID ||
          die "无法读取 Cloudflare Zone ID"
      fi
    fi
    if [ "$NEZHA_MENU_SELECTED" -eq 1 ]; then
      apply_nezha_host_defaults
    fi
  fi
  if [ "$SKIP_NYA" -ne 1 ]; then
    prompt_missing NYA_TOKEN 'NyanPass Token（隐藏输入）：' 1
    prompt_missing NYA_URL 'NyanPass 服务 URL：'
  fi
  if [ "$SKIP_IP_ROTATE" -ne 1 ]; then
    prompt_missing AWS_TOKEN 'aws.sb Token（隐藏输入）：' 1
    if [ -z "$AWS_SHARE_ID" ]; then
      read -r -p 'aws.sb Share ID（可留空按本机实例自动查询）：' AWS_SHARE_ID ||
        die "无法读取 aws.sb Share ID"
    fi
    if [ -z "$AWS_REGION" ]; then
      read -r -p 'AWS Region（可留空自动获取）：' AWS_REGION || die "无法读取 AWS Region"
    fi
  fi
  if [ "$SKIP_NEZHA" -ne 1 ]; then
    prompt_missing NEZHA_SERVER '哪吒面板地址（HOST:PORT）：'
    prompt_missing NEZHA_CLIENT_SECRET '哪吒 Client Secret（隐藏输入）：' 1
    prompt_missing NEZHA_UUID '哪吒 UUID：'
    if [ "$NEZHA_DEFAULTS_APPLIED" -ne 1 ]; then
      read -r -p "哪吒 TLS [true/false，默认 ${NEZHA_TLS}]：" nezha_tls_input ||
        die "无法读取哪吒 TLS 设置"
      NEZHA_TLS="${nezha_tls_input:-$NEZHA_TLS}"
    fi
  fi
fi

if [ "$SKIP_CADU" -eq 1 ] && \
   { [ "$SKIP_DDNS" -ne 1 ] || [ "$SKIP_IP_ROTATE" -ne 1 ] || [ "$SKIP_OPTIMIZE" -ne 1 ]; }; then
  die "DDNS、自动换 IP 和系统优化依赖 CADU；跳过 CADU 时也必须跳过这三项"
fi

case "$DDNS_PROVIDER" in
  aliyun|cloudflare|both) ;;
  *) die "--provider must be aliyun, cloudflare or both" ;;
esac

if [ "$SKIP_NYA" -ne 1 ]; then
  for required in NYA_TOKEN NYA_URL; do
    [ -n "${!required}" ] || die "missing required option for $required"
  done
fi
if [ "$SKIP_NEZHA" -ne 1 ]; then
  for required in NEZHA_SERVER NEZHA_CLIENT_SECRET NEZHA_UUID; do
    [ -n "${!required}" ] || die "missing required option for $required"
  done
  [[ "$NEZHA_SERVER" == *:* ]] || die "--nezha-server must be HOST:PORT"
  [[ "$NEZHA_TLS" == "true" || "$NEZHA_TLS" == "false" ]] ||
    die "--nezha-tls must be true or false"
  [[ "$NEZHA_UUID" =~ ^[0-9A-Fa-f-]{36}$ ]] || die "--nezha-uuid must be a UUID"
fi
if [ "$SKIP_IP_ROTATE" -ne 1 ]; then
  [ -n "$AWS_TOKEN" ] || die "missing required option for AWS_TOKEN"
fi

if [ "$SKIP_DDNS" -ne 1 ] && \
   { [ "$DDNS_PROVIDER" = "aliyun" ] || [ "$DDNS_PROVIDER" = "both" ]; }; then
  for required in ALIYUN_KEY_ID ALIYUN_KEY_SECRET ALIYUN_HOST; do
    [ -n "${!required}" ] || die "missing required option for $required"
  done
  [[ "$ALIYUN_HOST" == *.* ]] || die "--aliyun-host must be RR.DOMAIN"
fi
if [ "$SKIP_DDNS" -ne 1 ] && \
   { [ "$DDNS_PROVIDER" = "cloudflare" ] || [ "$DDNS_PROVIDER" = "both" ]; }; then
  for required in CF_TOKEN CF_HOST; do
    [ -n "${!required}" ] || die "missing required option for $required"
  done
  [[ "$CF_HOST" == *.* ]] || die "--cf-host must be RR.DOMAIN"
fi
if [ "$SKIP_NYA" -ne 1 ]; then
  [[ "$NYA_URL" == https://* ]] || die "--nya-url must use HTTPS"
  NYA_HOST="${NYA_URL#https://}"
  NYA_HOST="${NYA_HOST%%/*}"
  NYA_HOST="${NYA_HOST%%:*}"
  [ -n "$NYA_HOST" ] || die "--nya-url does not contain a valid host"
  case "$NYA_HOST" in
    example|example.*|*.example|*.example.*|*.invalid|*.test)
      die "--nya-url still uses a placeholder/reserved domain: $NYA_HOST"
      ;;
  esac
fi
[[ "$CADU_BASE_URL" == https://* ]] || die "CADU_BASE_URL must use HTTPS"
if [ -n "$NYA_SERVICE_NAME" ]; then
  [[ "$NYA_SERVICE_NAME" =~ ^[A-Za-z0-9_-]+$ ]] ||
    die "--nya-service-name only accepts letters, numbers, underscore and hyphen"
fi

[ "$(id -u)" -eq 0 ] || die "bootstrap must run as root"

network_ready=0
for _ in $(seq 1 60); do
  if curl -fsS --connect-timeout 5 "${CADU_BASE_URL%/}/install.sh" >/dev/null; then
    network_ready=1
    break
  fi
  sleep 5
done
[ "$network_ready" -eq 1 ] || die "timed out waiting for CADU download endpoint"

if [ "$SKIP_CADU" -eq 1 ]; then
  printf 'Skipping CADU installation...\n'
else
  printf 'Installing CADU...\n'
  CADU_BASE_URL="${CADU_BASE_URL%/}" \
    bash <(curl -fsSL --retry 5 --retry-delay 3 "${CADU_BASE_URL%/}/install.sh")
fi

if [ "$SKIP_DDNS" -eq 1 ]; then
  printf 'Skipping CADU DDNS; disabling an existing service if present...\n'
  systemctl disable --now cadu-ddns.service >/dev/null 2>&1 || true
else
  printf 'Installing DDNS service...\n'
  ddns_args=(--provider "$DDNS_PROVIDER")
  if [ "$DDNS_PROVIDER" = "aliyun" ] || [ "$DDNS_PROVIDER" = "both" ]; then
    ddns_args+=(--aliyun-host "$ALIYUN_HOST")
  fi
  if [ "$DDNS_PROVIDER" = "cloudflare" ] || [ "$DDNS_PROVIDER" = "both" ]; then
    ddns_args+=(--cloudflare-host "$CF_HOST")
  fi
  ALIYUN_ACCESS_KEY_ID="$ALIYUN_KEY_ID" \
  ALIYUN_ACCESS_KEY_SECRET="$ALIYUN_KEY_SECRET" \
  CLOUDFLARE_API_TOKEN="$CF_TOKEN" \
  CLOUDFLARE_ZONE_ID="$CF_ZONE_ID" \
    cadu-ddns "${ddns_args[@]}"
fi

bootstrap_state_dir="$(dirname "$BOOTSTRAP_MARKER")"
nya_name_file="${bootstrap_state_dir}/nyanpass-service-name"
install -d -m 700 "$bootstrap_state_dir"

install_nya_dns() {
  local dns_conf="/etc/dnsmasq.d/cadu-nya.conf"
  local resolv_backup="${bootstrap_state_dir}/resolv.conf.original"
  local existing_conf

  if dpkg-query -W -f='${db:Status-Abbrev}' systemd-resolved 2>/dev/null | grep -q '^ii'; then
    printf 'WARNING: systemd-resolved is installed; skipping NyanPass local DNS setup.\n' >&2
    SKIP_NYA_DNS=1
    return 0
  fi
  if systemctl is-active --quiet systemd-resolved.service 2>/dev/null; then
    printf 'WARNING: systemd-resolved is active; skipping NyanPass local DNS setup.\n' >&2
    SKIP_NYA_DNS=1
    return 0
  fi

  if dpkg-query -W -f='${db:Status-Abbrev}' dnsmasq 2>/dev/null | grep -q '^ii'; then
    : >"${bootstrap_state_dir}/dnsmasq-preexisting"
  fi
  if systemctl is-active --quiet dnsmasq.service 2>/dev/null; then
    : >"${bootstrap_state_dir}/dnsmasq-was-active"
  fi

  if [ "$SKIP_DDNS" -eq 1 ]; then
    DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a \
      apt-get -o DPkg::Lock::Timeout=120 update -y
  fi
  DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a \
    apt-get -o DPkg::Lock::Timeout=120 install -y --no-install-recommends dnsmasq dnsutils

  existing_conf="$(find /etc/dnsmasq.d -maxdepth 1 -type f -name '*.conf' \
    ! -name 'cadu-nya.conf' -print -quit 2>/dev/null || true)"
  [ -z "$existing_conf" ] || die "existing dnsmasq configuration requires manual review: $existing_conf"

  cat >"$dns_conf" <<'DNSMASQ'
listen-address=127.0.53.53
bind-interfaces
no-resolv
strict-order
cache-size=1000
server=1.1.1.1
server=8.8.8.8
server=2606:4700:4700::1111
server=2001:4860:4860::8888
DNSMASQ

  dnsmasq --test
  systemctl enable --now dnsmasq.service
  systemctl restart dnsmasq.service
  dig +time=5 +tries=2 +short @127.0.53.53 cloudflare.com A | grep -Eq '^[0-9]+(\.[0-9]+){3}$' ||
    die "dnsmasq validation through 127.0.53.53 failed"

  if [ ! -e "$resolv_backup" ] && [ ! -L "$resolv_backup" ]; then
    cp -a /etc/resolv.conf "$resolv_backup"
  fi
  chattr -i /etc/resolv.conf 2>/dev/null || true
  rm -f /etc/resolv.conf
  printf 'nameserver 127.0.53.53\n' >/etc/resolv.conf
  chattr +i /etc/resolv.conf || printf 'WARNING: unable to make /etc/resolv.conf immutable\n' >&2
  : >"${bootstrap_state_dir}/nya-dns-installed"
}

if [ "$SKIP_NYA_DNS" -eq 1 ]; then
  printf 'Skipping NyanPass local DNS setup...\n'
else
  printf 'Installing validated local DNS for NyanPass...\n'
  install_nya_dns
fi

if [ -z "$NYA_SERVICE_NAME" ] && [ -s "$nya_name_file" ]; then
  NYA_SERVICE_NAME="$(tr -d '[:space:]' <"$nya_name_file")"
fi
if [ "$SKIP_NYA" -eq 1 ]; then
  printf 'Skipping NyanPass installation...\n'
  if [[ -n "$NYA_SERVICE_NAME" && "$NYA_SERVICE_NAME" =~ ^[A-Za-z0-9_-]+$ ]]; then
    systemctl disable --now "${NYA_SERVICE_NAME}.service" >/dev/null 2>&1 || true
  fi
else
  printf 'Validating NyanPass service hostname: %s...\n' "$NYA_HOST"
  if [ "$SKIP_NYA_DNS" -eq 1 ]; then
    getent ahostsv4 "$NYA_HOST" >/dev/null 2>&1 ||
      die "NyanPass service hostname cannot be resolved: $NYA_HOST"
  else
    dig +time=5 +tries=2 +short @127.0.53.53 "$NYA_HOST" A |
      grep -Eq '^[0-9]+(\.[0-9]+){3}$' ||
      die "NyanPass service hostname cannot be resolved through local DNS: $NYA_HOST"
  fi
  if [ -z "$NYA_SERVICE_NAME" ]; then
    random_suffix="$(od -An -N6 -tx1 /dev/urandom | tr -d '[:space:]')"
    NYA_SERVICE_NAME="$random_suffix"
  fi
  [[ "$NYA_SERVICE_NAME" =~ ^[A-Za-z0-9_-]+$ ]] || die "invalid persisted NyanPass service name"
  printf '%s\n' "$NYA_SERVICE_NAME" >"$nya_name_file"
  chmod 600 "$nya_name_file"

  if systemctl cat "${NYA_SERVICE_NAME}.service" >/dev/null 2>&1; then
    printf 'NyanPass service %s already exists; skipping installation.\n' "$NYA_SERVICE_NAME"
  else
    printf 'Installing NyanPass node client as %s...\n' "$NYA_SERVICE_NAME"
    S="$NYA_SERVICE_NAME" bash <(curl -fLSs --retry 5 --retry-delay 3 "$NYA_INSTALL_URL") \
      rel_nodeclient "-t $NYA_TOKEN -u $NYA_URL"
  fi
fi

require_active_service() {
  local service="$1"
  systemctl is-active --quiet "$service" || die "$service is not active; stopping before high-risk tasks"
}

if [ "$SKIP_DDNS" -ne 1 ]; then
  require_active_service cadu-ddns.service
fi
if [ "$SKIP_NYA" -ne 1 ]; then
  require_active_service "${NYA_SERVICE_NAME}.service"
fi

resolve_nezha_config() {
  local exec_start config

  exec_start="$(systemctl show nezha-agent.service --property=ExecStart --value 2>/dev/null || true)"
  config="$(printf '%s\n' "$exec_start" | sed -n 's/.* -c \([^ ;}]*config[^ ;}]*\.yml\).*/\1/p')"
  if [ -n "$config" ] && [ -f "$config" ]; then
    printf '%s\n' "$config"
    return 0
  fi

  find /opt/nezha/agent -maxdepth 1 -type f -name '*config*.yml' -printf '%T@ %p\n' \
    2>/dev/null | sort -nr | sed -n '1s/^[^ ]* //p'
}

install_nezha_agent() {
  local installer attempt

  installer="$(mktemp)"
  for attempt in 1 2 3; do
    printf 'Nezha Agent install attempt %s/3...\n' "$attempt"
    if curl -fsSL --retry 5 --retry-delay 3 \
         https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.sh \
         -o "$installer" && \
       env \
         NZ_SERVER="$NEZHA_SERVER" \
         NZ_TLS="$NEZHA_TLS" \
         NZ_CLIENT_SECRET="$NEZHA_CLIENT_SECRET" \
         NZ_UUID="$NEZHA_UUID" \
         bash "$installer" && \
       systemctl cat nezha-agent.service >/dev/null 2>&1; then
      rm -f "$installer"
      return 0
    fi
    sleep $((attempt * 3))
  done
  rm -f "$installer"
  return 1
}

set_nezha_config_value() {
  local key="$1"
  local value="$2"
  local config="$3"

  if grep -q "^${key}:" "$config"; then
    sed -i "s/^${key}:.*/${key}: ${value}/" "$config"
  else
    printf '%s: %s\n' "$key" "$value" >>"$config"
  fi
}

if [ "$SKIP_NEZHA" -eq 1 ]; then
  printf 'Skipping Nezha Agent installation...\n'
else
  printf 'Installing Nezha Agent...\n'
  if ! systemctl is-active --quiet nezha-agent.service || \
     [ ! -x /opt/nezha/agent/nezha-agent ]; then
    install_nezha_agent || die "Nezha Agent installation failed after 3 attempts"
  fi
  NEZHA_CONFIG="$(resolve_nezha_config)"
  if [ -z "$NEZHA_CONFIG" ] || [ ! -f "$NEZHA_CONFIG" ]; then
    die "Nezha Agent active config was not found"
  fi
  printf 'Nezha Agent config: %s\n' "$NEZHA_CONFIG"
  set_nezha_config_value report_delay 4 "$NEZHA_CONFIG"
  systemctl restart nezha-agent.service
  require_active_service nezha-agent.service
fi

if [ "$SKIP_IP_ROTATE" -eq 1 ]; then
  printf 'Skipping CADU IP rotation; disabling an existing service if present...\n'
  systemctl disable --now cadu-ip-rotate.service >/dev/null 2>&1 || true
else
  printf 'Installing aws.sb IP rotation service...\n'
  ip_rotate_args=()
  case "$DDNS_PROVIDER" in
    aliyun) ip_rotate_control_id="$ALIYUN_HOST" ;;
    cloudflare|both) ip_rotate_control_id="$CF_HOST" ;;
  esac
  if [ -n "$ip_rotate_control_id" ]; then
    ip_rotate_args+=(--control-id "$ip_rotate_control_id")
  fi
  if [ -n "$AWS_SHARE_ID" ]; then
    ip_rotate_args+=(--aws-share-id "$AWS_SHARE_ID")
  fi
  if [ -n "$AWS_REGION" ]; then
    ip_rotate_args+=(--aws-region "$AWS_REGION")
  fi
  AWS_SB_SHARE_GROUP_TOKEN="$AWS_TOKEN" \
  CADU_SKIP_APT_UPDATE=1 \
    cadu-ip-rotate "${ip_rotate_args[@]}"
fi

if [ "$SKIP_OPTIMIZE" -eq 1 ]; then
  printf 'Skipping CADU test-server optimization...\n'
else
  printf 'Applying CADU test-server optimization last...\n'
  cadu --optimize --yes
fi

printf 'completed_at=%s\n' "$(date -Is)" >"$BOOTSTRAP_MARKER"
chmod 600 "$BOOTSTRAP_MARKER"

show_service_result() {
  local service="$1"
  local state

  state="$(systemctl is-active "$service" 2>/dev/null || true)"
  printf '%-32s %s\n' "$service" "${state:-unknown}"
  journalctl -u "$service" -n 8 --no-pager 2>/dev/null || true
}

printf '\n========== CADU bootstrap result ==========\n'
if [ "$SKIP_DDNS" -ne 1 ] && \
   { [ "$DDNS_PROVIDER" = "aliyun" ] || [ "$DDNS_PROVIDER" = "both" ]; }; then
  printf 'Aliyun DDNS:     %s\n' "$ALIYUN_HOST"
  getent ahostsv4 "$ALIYUN_HOST" 2>/dev/null | awk '!seen[$1]++ {print "  " $1}' || \
    printf '  DNS record is not resolvable yet.\n'
fi
if [ "$SKIP_DDNS" -ne 1 ] && \
   { [ "$DDNS_PROVIDER" = "cloudflare" ] || [ "$DDNS_PROVIDER" = "both" ]; }; then
  printf 'Cloudflare DDNS: %s\n' "$CF_HOST"
  getent ahostsv4 "$CF_HOST" 2>/dev/null | awk '!seen[$1]++ {print "  " $1}' || \
    printf '  DNS record is not resolvable yet.\n'
fi
if [ "$SKIP_NYA" -eq 1 ]; then
  printf 'NyanPass:        skipped/disabled\n\n'
else
  printf 'NyanPass name:   %s\n\n' "$NYA_SERVICE_NAME"
fi

if [ "$SKIP_NYA_DNS" -eq 1 ]; then
  printf '%-32s %s\n' 'dnsmasq.service' 'skipped'
else
  show_service_result dnsmasq.service
fi
if [ "$SKIP_DDNS" -eq 1 ]; then
  printf '%-32s %s\n' 'cadu-ddns.service' 'skipped/disabled'
else
  show_service_result cadu-ddns.service
fi
if [ "$SKIP_IP_ROTATE" -eq 1 ]; then
  printf '%-32s %s\n' 'cadu-ip-rotate.service' 'skipped/disabled'
else
  show_service_result cadu-ip-rotate.service
fi
if [ "$SKIP_NYA" -eq 1 ]; then
  printf '%-32s %s\n' 'NyanPass service' 'skipped/disabled'
else
  show_service_result "${NYA_SERVICE_NAME}.service"
fi
if [ "$SKIP_NEZHA" -eq 1 ]; then
  printf '%-32s %s\n' 'nezha-agent.service' 'skipped'
else
  show_service_result nezha-agent.service
fi
printf 'Marker: %s\n' "$BOOTSTRAP_MARKER"
printf 'Bootstrap completed.\n'
