#!/usr/bin/env bash
# Pure, sourceable helpers for ArchForge External Status domain/TLS configuration.
# Deliberately never source status.env; it contains literal secrets.

af_valid_domain() {
  local domain=${1-} label
  [[ ${#domain} -le 253 && "$domain" == *.* && "$domain" != *..* && "$domain" != .* && "$domain" != *. ]] || return 1
  [[ "$domain" =~ ^[a-zA-Z0-9.-]+$ ]] || return 1
  local IFS=.
  local -a labels
  read -r -a labels <<< "$domain"
  for label in "${labels[@]}"; do
    [[ ${#label} -ge 1 && ${#label} -le 63 && "$label" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$ ]] || return 1
  done
  return 0
}

af_valid_ipv4() {
  local ip=${1-} part
  [[ "$ip" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]] || return 1
  local IFS=.
  local -a octets
  read -r -a octets <<< "$ip"
  [[ ${#octets[@]} == 4 ]] || return 1
  for part in "${octets[@]}"; do
    [[ ${#part} -le 3 && ( "$part" == 0 || "$part" != 0* ) ]] || return 1
    (( 10#$part <= 255 )) || return 1
  done
  return 0
}

af_valid_ipv6() {
  [[ -n ${1-} ]] || return 1
  python3 -c 'import ipaddress,sys;ipaddress.IPv6Address(sys.argv[1])' "$1" >/dev/null 2>&1
}

af_valid_email() {
  local mail=${1-}
  [[ -z "$mail" || ( "$mail" =~ ^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$ && ${#mail} -le 254 ) ]]
}

af_read_public_domain() {
  local env_file=$1 url
  [[ -f "$env_file" && ! -L "$env_file" ]] || return 1
  url=$(grep -m1 '^STATUS_PUBLIC_URL=' "$env_file" | cut -d= -f2-) || return 1
  [[ "$url" == https://* ]] || return 1
  url=${url#https://}
  [[ "$url" != */* ]] || return 1
  af_valid_domain "$url" || return 1
  printf '%s' "$url"
}

af_set_public_domain() {
  local env_file=$1 domain=$2 tmp
  af_valid_domain "$domain" || return 1
  [[ -f "$env_file" && ! -L "$env_file" ]] || return 1
  tmp=$(mktemp "$(dirname "$env_file")/.status-env.XXXXXXXX") || return 1
  chmod --reference="$env_file" "$tmp"
  chown --reference="$env_file" "$tmp"
  if ! awk -v new="STATUS_PUBLIC_URL=https://${domain}" '
    /^STATUS_PUBLIC_URL=/ { if (!seen++) print new; next }
    { print }
    END { if (!seen) print new }
  ' "$env_file" > "$tmp"; then
    rm -f "$tmp"
    return 1
  fi
  mv -f -- "$tmp" "$env_file"
}

af_render_caddy() {
  local domain=$1 email=${2-}
  af_valid_domain "$domain" && af_valid_email "$email" || return 1
  printf '%s {\n' "$domain"
  printf '    encode zstd gzip\n'
  printf '    reverse_proxy 127.0.0.1:3000\n'
  if [[ -n "$email" ]]; then
    printf '    tls %s\n' "$email"
  fi
  printf '}\n'
}

af_dns_records() {
  local type=$1 domain=$2
  [[ "$type" == A || "$type" == AAAA ]] && af_valid_domain "$domain" || return 1
  dig +time=3 +tries=1 +short "$type" "$domain" | grep -E "$( [[ "$type" == A ]] && printf '^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$' || printf '^[0-9A-Fa-f:]+$' )" || true
}
