#!/bin/bash
# change_domain_hostname.sh
# Safely change the system hostname and Avahi mDNS domain name, update /etc/hosts, restart Avahi,
# and generate a per-device certificate signed by the CA.
# Usage: sudo ./change_domain_hostname.sh <new_hostname> <new_domain> [--force]

set -e

if [ "$EUID" -ne 0 ]; then
    echo "Please run as root."
    exit 1
fi

if [ $# -lt 2 ]; then
    echo "Usage: sudo $0 <new_hostname> <new_domain> [--force]"
    exit 1
fi

NEW_HOSTNAME="$1"
NEW_DOMAIN="$2"
FORCE=0
if [ "$3" == "--force" ]; then
    FORCE=1
fi

# Validate hostname: single label, no dots
if [[ "$NEW_HOSTNAME" == *.* ]]; then
    echo "ERROR: Hostname must not contain dots."
    exit 1
fi

# Set system hostname
hostnamectl set-hostname "$NEW_HOSTNAME"
echo "/etc/hostname set to $NEW_HOSTNAME."

# Update /etc/hosts
if grep -q '^127.0.1.1' /etc/hosts; then
    sed -i "s/^127.0.1.1.*/127.0.1.1   $NEW_HOSTNAME/" /etc/hosts
else
    echo "127.0.1.1   $NEW_HOSTNAME" >> /etc/hosts
fi
echo "/etc/hosts updated."

# Set Avahi domain name
AVAHI_CONF="/etc/avahi/avahi-daemon.conf"
sed -i "/^\[server\]/,/^\s*\[/{s/^\s*domain-name\s*=.*/domain-name=$NEW_DOMAIN/}" "$AVAHI_CONF"
echo "Set Avahi domain name to $NEW_DOMAIN."

# Restart Avahi
echo "Restarting avahi-daemon..."
systemctl restart avahi-daemon

echo "Done. Hostname: $NEW_HOSTNAME, Avahi domain: $NEW_DOMAIN"

# --- Per-device certificate logic ---
CA_DIR="$(dirname "$0")/certs/ca"
PER_DEVICE_DIR="$(dirname "$0")/certs/per_device/$NEW_HOSTNAME.$NEW_DOMAIN"
mkdir -p "$PER_DEVICE_DIR"
CA_CERT="$CA_DIR/ca_cert.pem"
CA_KEY="$CA_DIR/ca_key.pem"
DEVICE_CERT="$PER_DEVICE_DIR/device_cert.pem"
DEVICE_KEY="$PER_DEVICE_DIR/device_key.pem"
DEVICE_CSR="$PER_DEVICE_DIR/device.csr"
SAN_CNF="$PER_DEVICE_DIR/san.cnf"

if [ -f "$DEVICE_CERT" ] && [ $FORCE -eq 0 ]; then
    echo "Per-device certificate already exists at $DEVICE_CERT. Use --force to regenerate."
else
    echo "Generating per-device key/cert for $NEW_HOSTNAME.$NEW_DOMAIN..."
    openssl genrsa -out "$DEVICE_KEY" 4096
    cat > "$SAN_CNF" <<EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = $NEW_HOSTNAME.$NEW_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = $NEW_HOSTNAME.$NEW_DOMAIN
EOF
    openssl req -new -key "$DEVICE_KEY" -out "$DEVICE_CSR" -config "$SAN_CNF"
    openssl x509 -req -in "$DEVICE_CSR" -CA "$CA_CERT" -CAkey "$CA_KEY" -CAcreateserial -out "$DEVICE_CERT" -days 7300 -extensions v3_req -extfile "$SAN_CNF"
    echo "Per-device certificate generated at $DEVICE_CERT."
fi
