#!/bin/bash
# DNS Server: optional local macOS DNS configuration, user-confirmed.
# Usage: bash dns-switch-macos.sh apply cloudflare
# Undo:  bash dns-switch-macos.sh restore
set -euo pipefail
action="${1:-apply}"
provider="${2:-cloudflare}"
case "$provider" in
 cloudflare) ip1="1.1.1.1";ip2="1.0.0.1";;
 google) ip1="8.8.8.8";ip2="8.8.4.4";;
 quad9) ip1="9.9.9.9";ip2="149.112.112.112";;
 *) echo "Unknown provider";exit 1;;
esac
[[ "$action" == "apply" || "$action" == "restore" ]] || exit 1
command -v networksetup >/dev/null || { echo "macOS required";exit 1;}
services=()
while IFS= read -r item;do
 [[ -n "$item" && "$item" != \** ]] && services+=("$item")
done < <(networksetup -listallnetworkservices | tail -n +2)
[[ ${#services[@]} -gt 0 ]] || { echo "No enabled network services";exit 1;}
echo "Choose the network service you want to change."
for i in "${!services[@]}";do printf '[%s] %s\n' "$((i+1))" "${services[$i]}";done
read -r -p "Service number or q: " answer
[[ "$answer" != "q" ]] || exit 0
[[ "$answer" =~ ^[0-9]+$ ]] || exit 1
((answer >= 1 && answer <= ${#services[@]})) || exit 1
service="${services[$((answer-1))]}"
key="$(printf '%s' "$service" | shasum -a 256 | cut -c1-16)"
folder="$HOME/.dns-server"
backup="$folder/backup-$key.txt"
if [[ "$action" == "restore" ]];then
 [[ -f "$backup" ]] || { echo "Missing backup";exit 1;}
 old=()
 while IFS= read -r line;do old+=("$line");done < "$backup"
 echo "Restore DNS for $service?"
 read -r -p "Type RESTORE: " confirm
 [[ "$confirm" == "RESTORE" ]] || exit 0
 if [[ "${old[0]:-AUTO}" == "AUTO" ]];then
  sudo networksetup -setdnsservers "$service" Empty
 else
  sudo networksetup -setdnsservers "$service" "${old[@]}"
 fi
 echo "Restored; backup retained."
 exit 0
fi
[[ ! -f "$backup" ]] || { echo "Backup already exists; restore or move it first.";exit 1;}
before="$(networksetup -getdnsservers "$service")"
printf 'Old DNS: %s\nNew DNS: %s, %s\n' "$before" "$ip1" "$ip2"
read -r -p "Type APPLY to back up and change DNS: " confirm
[[ "$confirm" == "APPLY" ]] || exit 0
mkdir -p "$folder"
chmod 700 "$folder"
umask 077
if [[ "$before" == *"There aren't any DNS Servers set on"* ]];then
 printf 'AUTO\n' > "$backup"
else
 printf '%s\n' "$before" > "$backup"
fi
sudo networksetup -setdnsservers "$service" "$ip1" "$ip2"
echo "DNS updated. Backup at $backup; restore with bash dns-switch-macos.sh restore."