#!/usr/bin/env bash
# Idempotent installation for Ubuntu/Debian unattended-upgrades + msmtp.
set -Eeuo pipefail
export DEBIAN_FRONTEND=noninteractive
[[ $EUID -eq 0 ]] || { echo 'Kör som root (su -) eller med sudo.' >&2; exit 1; }
. /etc/os-release
[[ ${ID:-} == ubuntu || ${ID:-} == debian ]] || { echo 'Endast Ubuntu/Debian stöds.' >&2; exit 1; }
command -v systemctl >/dev/null || { echo 'Systemd krävs.' >&2; exit 1; }

SMTP_HOST=192.168.0.7
SMTP_PORT=25
FROM="linux-updates@$(hostname -f 2>/dev/null || hostname)"
RECIPIENTS='dennis@ern.se, carsten@mrnobody.nu'
APT_DIR=/etc/apt/apt.conf.d
BACKUP_DIR=/var/backups/linux-auto-update
CHANGES=0
STAMP=$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP_DIR"

backup_file() {
  local path=$1
  if [[ -f $path ]]; then
    local dest="$BACKUP_DIR/$(basename "$path").$STAMP.bak"
    cp -a -- "$path" "$dest"
    echo "Backup: $dest"
  fi
}
# Update only when contents differ. Avoid repeatedly changing files/backing them up.
write_if_changed() {
  local dest=$1 tmp
  tmp=$(mktemp)
  cat > "$tmp"
  if [[ -f $dest ]] && cmp -s "$tmp" "$dest"; then
    echo "Redan korrekt: $dest"
    rm -f "$tmp"
    return
  fi
  backup_file "$dest"
  install -m 644 -o root -g root "$tmp" "$dest"
  rm -f "$tmp"
  echo "Konfigurerad: $dest"
  CHANGES=$((CHANGES+1))
}

printf '\n=== Linux Auto Update – Ubuntu/Debian ===\nSystem: %s\nSMTP: %s:%s\nMottagare: %s\n' "${PRETTY_NAME:-$ID}" "$SMTP_HOST" "$SMTP_PORT" "$RECIPIENTS"
echo 'Ingen automatisk omstart. Inga uppdateringar installeras av själva guiden.'
read -r -p 'Fortsätta? [j/N]: ' consent
[[ ${consent,,} == j || ${consent,,} == ja ]] || exit 0

# Disable only dedicated Zabbix source files, never shared source lists.
echo '[1/5] Kontrollerar gamla Zabbix-källor...'
shopt -s nullglob
for file in /etc/apt/sources.list.d/*; do
  [[ -f $file ]] || continue
  case "$file" in *.list) ;; *.sources) echo "OBS: Zabbix i deb822-fil $file – granska manuellt."; continue ;; *) continue ;; esac
  if grep -Eiq 'repo\.zabbix\.com' "$file"; then
    # Only move a file if no other active repository entries exist.
    if [[ $file == *.list ]] && grep -E '^[[:space:]]*deb(-src)?[[:space:]]' "$file" | grep -Ev 'repo\.zabbix\.com' | grep -q .; then
      echo "VARNING: Blandad källfil $file – lämnas orörd."
    elif [[ $file == *.sources ]] && grep -E '^URIs:' "$file" | grep -Ev 'repo\.zabbix\.com' | grep -q .; then
      echo "VARNING: Blandad källfil $file – lämnas orörd."
    else
      mkdir -p "$BACKUP_DIR/zabbix"
      mv -- "$file" "$BACKUP_DIR/zabbix/$(basename "$file").$STAMP.disabled"
      echo "Inaktiverade Zabbix-källa: $file"
      CHANGES=$((CHANGES+1))
    fi
  fi
done
if [[ -f /etc/apt/sources.list ]] && grep -Eq '^[[:space:]]*deb(-src)?[[:space:]].*repo\.zabbix\.com' /etc/apt/sources.list; then
  backup_file /etc/apt/sources.list
  sed -i -E '/^[[:space:]]*deb(-src)?[[:space:]].*repo\.zabbix\.com/s/^/# disabled old Zabbix: /' /etc/apt/sources.list
  CHANGES=$((CHANGES+1))
fi

# Check package presence before running apt-get update/install.
echo '[2/5] Kontrollerar paket...'
missing=()
for pkg in unattended-upgrades msmtp-mta ca-certificates; do
  if ! dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -qx 'install ok installed'; then
    missing+=("$pkg")
  fi
done
if ((${#missing[@]})); then
  echo "Installerar saknade paket: ${missing[*]}"
  apt-get update
  apt-get install -y "${missing[@]}"
  CHANGES=$((CHANGES+1))
else
  echo 'Alla nödvändiga paket är redan installerade.'
fi

# Ubuntu and Debian each use their own repository metadata.
echo '[3/5] Kontrollerar automatisk APT-konfiguration...'
write_if_changed "$APT_DIR/20auto-upgrades" <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
EOF
if [[ $ID == ubuntu ]]; then
  ORIGIN_LINE='"origin=Ubuntu,archive=${distro_codename}-updates";'
else
  ORIGIN_LINE='"origin=Debian,codename=${distro_codename}-updates";'
fi
write_if_changed "$APT_DIR/51-auto-updates-stable" <<EOF
// Extra stable updates; existing security/ESM origins remain untouched.
Unattended-Upgrade::Origins-Pattern {
    $ORIGIN_LINE
};
EOF
write_if_changed "$APT_DIR/90-auto-updates-mail" <<'EOF'
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Dependencies "false";
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::MailReport "on-change";
EOF

# Preserve unrelated existing mail setups rather than silently overwriting them.
echo '[4/5] Kontrollerar SMTP...'
msmtp_tmp=$(mktemp)
cat > "$msmtp_tmp" <<EOF
defaults
syslog LOG_MAIL
aliases /etc/msmtp-auto-updates.aliases
account relay
host $SMTP_HOST
port $SMTP_PORT
from $FROM
auth off
tls off
account default : relay
EOF
if [[ -f /etc/msmtprc ]] && ! cmp -s "$msmtp_tmp" /etc/msmtprc; then
  echo 'OBS: /etc/msmtprc finns och skiljer sig från önskad konfiguration.'
  read -r -p 'Säkerhetskopiera och ersätta /etc/msmtprc? [j/N]: ' overwrite
  if [[ ${overwrite,,} != j && ${overwrite,,} != ja ]]; then
    echo 'SMTP-konfigurationen lämnades orörd.'
  else
    write_if_changed /etc/msmtprc < "$msmtp_tmp"
  fi
else
  write_if_changed /etc/msmtprc < "$msmtp_tmp"
fi
rm -f "$msmtp_tmp"
write_if_changed /etc/msmtp-auto-updates.aliases <<EOF
root: $RECIPIENTS
EOF
# Readable aliases are needed by msmtp when invoked without root privileges.
# Repair ownership and permissions even when file contents are unchanged.
# The alias file contains only recipient addresses, no secrets.
if [[ $(stat -c '%u:%g:%a' /etc/msmtp-auto-updates.aliases) != '0:0:644' ]]; then
  chown root:root /etc/msmtp-auto-updates.aliases
  chmod 644 /etc/msmtp-auto-updates.aliases
  echo 'Reparerade ägare/rättigheter: aliasfil (root:root 644)'
  CHANGES=$((CHANGES+1))
fi
# Do not expose credentials from an unrelated, pre-existing msmtp config.
if [[ -f /etc/msmtprc ]]; then
  if grep -Eq '^host[[:space:]]+192\.168\.0\.7[[:space:]]*$' /etc/msmtprc &&
     grep -Eq '^auth[[:space:]]+off[[:space:]]*$' /etc/msmtprc &&
     ! grep -Eq '^[[:space:]]*(password|passwordeval|user)[[:space:]]' /etc/msmtprc; then
    if [[ $(stat -c '%u:%g:%a' /etc/msmtprc) != '0:0:644' ]]; then
      chown root:root /etc/msmtprc
      chmod 644 /etc/msmtprc
      echo 'Reparerade ägare/rättigheter: /etc/msmtprc (root:root 644)'
      CHANGES=$((CHANGES+1))
    fi
  else
    echo 'OBS: /etc/msmtprc verkar innehålla annan SMTP-konfiguration; rättigheter ändras inte automatiskt.'
  fi
fi

# Older scripts left backups in apt.conf.d; move these aside without deleting them.
for file in "$APT_DIR"/*.backup-*; do
  [[ -f $file ]] || continue
  mv -- "$file" "$BACKUP_DIR/$(basename "$file")"
  echo "Flyttade gammal APT-backup: $(basename "$file")"
  CHANGES=$((CHANGES+1))
done

echo '[5/5] Verifierar...'
apt-config dump | grep -E '^(APT::Periodic::(Update-Package-Lists|Unattended-Upgrade)|Unattended-Upgrade::(Mail|MailReport|Automatic-Reboot)) ' || true
systemctl list-timers 'apt-daily*' --no-pager || true
if ((CHANGES==0)); then
  echo 'KLART: Alla kontrollerade inställningar var redan korrekta. Inga ändringar behövdes.'
else
  echo "KLART: $CHANGES ändring(ar) gjordes. Backup: $BACKUP_DIR"
fi
read -r -p 'Skicka valfritt SMTP-test ENDAST till Carsten? [j/N]: ' testmail
if [[ ${testmail,,} == j || ${testmail,,} == ja ]]; then
  { printf 'To: carsten@mrnobody.nu\nFrom: %s\nSubject: Test Linux Auto Update %s\n\n' "$FROM" "$(hostname)"; echo 'SMTP-test, inga uppdateringar har installerats.'; } | /usr/sbin/sendmail -t
  echo 'Testmejl överlämnat till SMTP-klienten.'
fi
echo 'För riktig körning: sudo unattended-upgrade -v'
echo 'OBS: Ubuntu 20.04 kräver Ubuntu Pro/ESM eller OS-uppgradering för fortsatt säkerhetsunderhåll.'
