#!/usr/bin/env bash
# commands/peer/update-dns.sh

function cmd::peer::update_dns::on_load() {
  help::section "Target"
  flag::define --name value "Peer name"          label:name section:Target
  flag::define --type value "Filter by type"     label:type section:Target
  flag::define --all  bool  "Update all peers"   section:Target

  help::section "DNS"
  flag::define --dns          value "Primary DNS server"   label:ip section:DNS
  flag::define --fallback-dns value "Fallback DNS servers" label:ips section:DNS
}

function cmd::peer::update_dns::run() {
  flag::parse "$@" || return 1

  local name; name=$(flag::value --name)
  local type; type=$(flag::value --type)
  local dns;  dns=$(flag::value --dns)
  local fallback_dns; fallback_dns=$(flag::value --fallback-dns)
  local all=false
  flag::bool --all && all=true

  [[ -z "$name" && "$all" == "false" ]] && \
    log::error "Specify --name or --all" && return 1

  local primary="${dns:-$(config::dns)}"
  local fallback="${fallback_dns:-$(config::dns_fallback)}"
  local dns_string
  if [[ -n "$fallback" ]]; then
    dns_string="${primary}, ${fallback}"
  else
    dns_string="$primary"
  fi

  local -a peers=()
  if $all; then
    while IFS= read -r conf; do
      peers+=("$(basename "$conf" .conf)")
    done < <(find "$(ctx::clients)" -name "*.conf" 2>/dev/null)
  else
    name=$(peers::resolve_and_require "$name" "$type") || return 1
    peers=("$name")
  fi

  local updated=0
  for peer_name in "${peers[@]}"; do
    local conf
    conf="$(ctx::clients)/${peer_name}.conf"
    [[ ! -f "$conf" ]] && continue
    if grep -q "^DNS" "$conf"; then
      sed -i "s|^DNS = .*|DNS = ${dns_string}|" "$conf"
    else
      sed -i "/^Address/a DNS = ${dns_string}" "$conf"
    fi
    (( updated++ )) || true
    log::debug "Updated DNS for: ${peer_name}"
  done

  log::wg_success "Updated DNS to '${dns_string}' for ${updated} peer(s)"
}