#!/usr/bin/env bash
# Enterprise Mail — installer for Ubuntu Server.
#
# Installs/verifies OS packages this project needs: Node.js 22 LTS,
# PostgreSQL, Postfix, Dovecot, Apache2 (+ required modules). Safe to run
# more than once — every step is idempotent and existing configuration is
# backed up before anything is changed, never blindly overwritten.
#
# This script does NOT write Postfix/Dovecot mail-routing configuration —
# see deploy/postfix/README.md and deploy/dovecot/README.md for that; mail
# server config is too host-specific (existing domains, other mailboxes) to
# safely automate. It only ensures the packages and services exist.
#
# Usage: sudo ./scripts/install.sh

set -euo pipefail

# This deployment lives under the `server` user's home directory, not the
# more typical /var/www/html — override with: sudo APP_ROOT=/path ./install.sh
APP_ROOT="${APP_ROOT:-/home/server/namail}"
APP_USER="${APP_USER:-server}"
BACKUP_DIR="/var/backups/enterprise-mail/install-$(date +%Y%m%d%H%M%S)"

log()  { printf '\033[1;34m[install]\033[0m %s\n' "$1"; }
warn() { printf '\033[1;33m[install][warn]\033[0m %s\n' "$1"; }
die()  { printf '\033[1;31m[install][error]\033[0m %s\n' "$1" >&2; exit 1; }

[[ $EUID -eq 0 ]] || die "Run as root (sudo ./scripts/install.sh)."

# --- 1. Detect Ubuntu -------------------------------------------------------
. /etc/os-release 2>/dev/null || die "Cannot read /etc/os-release — is this Ubuntu?"
[[ "${ID:-}" == "ubuntu" ]] || warn "This script targets Ubuntu; detected ID=${ID:-unknown}. Continuing anyway."
log "Detected: ${PRETTY_NAME:-unknown}"

mkdir -p "$BACKUP_DIR"

backup_if_exists() {
  local path="$1"
  if [[ -e "$path" ]]; then
    local dest="$BACKUP_DIR$(dirname "$path")"
    mkdir -p "$dest"
    cp -a "$path" "$dest/"
    log "Backed up $path -> $dest/$(basename "$path")"
  fi
}

# --- 2. Base packages --------------------------------------------------------
log "Updating apt package lists..."
apt-get update -y

log "Installing base packages (curl, gnupg, ca-certificates, build tools)..."
apt-get install -y --no-install-recommends \
  curl gnupg ca-certificates apt-transport-https lsb-release

# --- 3. Node.js 22 LTS --------------------------------------------------------
NEED_NODE=1
if command -v node >/dev/null 2>&1; then
  NODE_MAJOR="$(node -v | sed -E 's/^v([0-9]+).*/\1/')"
  if [[ "$NODE_MAJOR" == "22" ]]; then
    log "Node.js 22 already installed ($(node -v)). Skipping."
    NEED_NODE=0
  else
    warn "Found Node.js $(node -v) — this project targets Node 22 LTS. Installing 22 via NodeSource (will become the active /usr/bin/node)."
  fi
fi
if [[ "$NEED_NODE" == "1" ]]; then
  curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
  apt-get install -y nodejs
fi
log "node: $(node -v), npm: $(npm -v)"

# --- 4. PostgreSQL ------------------------------------------------------------
if dpkg -l | grep -q '^ii.*postgresql-16\|^ii.*postgresql[[:space:]]'; then
  log "PostgreSQL already installed. Skipping install."
else
  log "Installing PostgreSQL..."
  apt-get install -y postgresql postgresql-contrib
fi
systemctl enable --now postgresql

# --- 5. Postfix ---------------------------------------------------------------
if dpkg -l | grep -q '^ii.*postfix'; then
  log "Postfix already installed. Skipping install (config NOT modified — see deploy/postfix/README.md)."
else
  log "Installing Postfix (select 'Internet Site' if prompted; hostname mail.nandalinux.com)..."
  backup_if_exists /etc/postfix/main.cf
  backup_if_exists /etc/postfix/master.cf
  DEBIAN_FRONTEND=noninteractive apt-get install -y postfix
fi

# --- 6. Dovecot ---------------------------------------------------------------
if dpkg -l | grep -q '^ii.*dovecot-imapd'; then
  log "Dovecot already installed. Skipping install (config NOT modified — see deploy/dovecot/README.md)."
else
  log "Installing Dovecot (IMAP + LMTP for local delivery)..."
  backup_if_exists /etc/dovecot/dovecot.conf
  apt-get install -y dovecot-imapd dovecot-lmtpd
fi

# --- 7. Apache2 + required modules -------------------------------------------
if dpkg -l | grep -q '^ii.*apache2[[:space:]]'; then
  log "Apache2 already installed."
else
  log "Installing Apache2..."
  apt-get install -y apache2
fi
log "Enabling required Apache modules..."
a2enmod proxy proxy_http proxy_wstunnel ssl headers rewrite expires deflate >/dev/null

# --- 8. Certbot (for Let's Encrypt) ------------------------------------------
if ! command -v certbot >/dev/null 2>&1; then
  log "Installing certbot..."
  apt-get install -y certbot python3-certbot-apache
fi

# --- 9. Directories & service user -------------------------------------------
log "Creating application directories under $APP_ROOT..."
mkdir -p "$APP_ROOT"/{backend/data/attachment-staging,frontend}
mkdir -p /var/mail/vhosts/nandalinux.com
id -u vmail >/dev/null 2>&1 || useradd -r -m -d /var/mail/vhosts -s /usr/sbin/nologin vmail
chown -R vmail:vmail /var/mail/vhosts
chown -R "$APP_USER:$APP_USER" "$APP_ROOT/backend/data" 2>/dev/null || true

# --- 10. PostgreSQL role + database (idempotent) -----------------------------
log "Ensuring PostgreSQL role/database exist (password NOT set here — set it yourself)..."
sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='enterprise_mail'" | grep -q 1 \
  || sudo -u postgres createuser enterprise_mail
sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='enterprise_mail'" | grep -q 1 \
  || sudo -u postgres createdb -O enterprise_mail enterprise_mail
warn "Set the enterprise_mail role's password yourself, then put it in backend/.env's DATABASE_URL:"
warn "  sudo -u postgres psql -c \"ALTER ROLE enterprise_mail WITH PASSWORD 'CHANGE_ME';\""

log "Base installation complete."
log "Backups of any pre-existing config: $BACKUP_DIR"
log "Next steps:"
log "  1. Copy backend/.env.example -> backend/.env and frontend/.env.example -> frontend/.env, fill in real values."
log "  2. Follow deploy/postfix/README.md and deploy/dovecot/README.md to configure mail routing for nandalinux.com."
log "  3. Run ./scripts/deploy.sh to build, migrate, and start the application services."
