#!/usr/bin/env bash
#
# One-time setup of an Ubuntu 24.04 server (e.g. AWS EC2) for the blog admin panel.
# Installs Node.js, Nginx, certbot and PM2, adds swap, creates the `cms` user
# and the folders the deploy script uses, and gives that user an SSH key for
# pulling the repository. Safe to run again.
#
#   sudo bash setup-server.sh
#
# The admin panel has no database: content lives on the Laravel CMS.
#
# Folder layout it creates:
#   /srv/secondline-cms/repo       git clone of the repository
#   /srv/secondline-cms/releases   one folder per deploy
#   /srv/secondline-cms/current    → the live release
#   /srv/secondline-cms/shared     .env and anything kept across releases
#   /srv/secondline-cms/logs       app logs
set -euo pipefail

APP_USER="${APP_USER:-cms}"
CMS_ROOT="${CMS_ROOT:-/srv/secondline-cms}"
NODE_MAJOR="${NODE_MAJOR:-22}"
SWAP_SIZE="${SWAP_SIZE:-2G}"
for arg in "$@"; do
  echo "Unknown option: $arg" >&2
  exit 1
done

if [[ $EUID -ne 0 ]]; then
  echo "Run as root: sudo bash $0" >&2
  exit 1
fi

step() { printf '\n==> %s\n' "$*"; }

step "System packages"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y ca-certificates curl gnupg git rsync nginx certbot python3-certbot-nginx

step "Node.js ${NODE_MAJOR}"
current_major="$(node -v 2>/dev/null | sed -E 's/^v([0-9]+).*/\1/' || true)"
if [[ "${current_major:-0}" -lt 20 ]]; then
  curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash -
  apt-get install -y nodejs
fi
node -v

step "PM2"
command -v pm2 >/dev/null || npm install -g pm2

step "Swap (${SWAP_SIZE}): next build needs more than 2 GB of memory"
if ! swapon --show | grep -q .; then
  fallocate -l "$SWAP_SIZE" /swapfile
  chmod 600 /swapfile
  mkswap /swapfile
  swapon /swapfile
  grep -q '^/swapfile ' /etc/fstab || echo '/swapfile none swap sw 0 0' >> /etc/fstab
fi
swapon --show

step "User ${APP_USER} and ${CMS_ROOT}"
id "$APP_USER" >/dev/null 2>&1 || useradd --create-home --shell /bin/bash "$APP_USER"
APP_HOME="$(getent passwd "$APP_USER" | cut -d: -f6)"
mkdir -p "$CMS_ROOT"/{releases,shared,logs}
chown -R "$APP_USER:$APP_USER" "$CMS_ROOT"
chmod 750 "$CMS_ROOT"

step "PM2 starts on boot as ${APP_USER}"
pm2 startup systemd -u "$APP_USER" --hp "$APP_HOME" >/dev/null
sudo -u "$APP_USER" -H pm2 ping >/dev/null
if ! sudo -u "$APP_USER" -H pm2 ls | grep -q pm2-logrotate; then
  sudo -u "$APP_USER" -H pm2 install pm2-logrotate >/dev/null
  sudo -u "$APP_USER" -H pm2 set pm2-logrotate:max_size 20M >/dev/null
  sudo -u "$APP_USER" -H pm2 set pm2-logrotate:retain 14 >/dev/null
fi

step "SSH key for pulling the repository"
# RSA: Azure DevOps accepts RSA keys for SSH (GitHub accepts them too).
if [[ ! -f "$APP_HOME/.ssh/id_rsa" ]]; then
  sudo -u "$APP_USER" -H mkdir -p "$APP_HOME/.ssh"
  sudo -u "$APP_USER" -H ssh-keygen -t rsa -b 4096 -N "" -C "${APP_USER}@$(hostname)" -f "$APP_HOME/.ssh/id_rsa" >/dev/null
fi
# Azure DevOps and GitHub host keys, so the first clone doesn't stop to ask.
sudo -u "$APP_USER" -H bash -c "ssh-keyscan -t rsa,ecdsa,ed25519 ssh.dev.azure.com github.com 2>/dev/null >> ~/.ssh/known_hosts; sort -u -o ~/.ssh/known_hosts ~/.ssh/known_hosts"

cat <<EOF

Done. Next steps (details in deploy/README.md):

1. Add this public key to Azure DevOps (User settings → SSH public keys),
   or as a read-only deploy key on GitHub:

$(cat "$APP_HOME/.ssh/id_rsa.pub")

2. Clone the repository:
   sudo -u ${APP_USER} -H git clone <ssh-url> ${CMS_ROOT}/repo

3. Nginx and HTTPS:
   sudo bash ${CMS_ROOT}/repo/deploy/setup-nginx.sh <domain> <email>

4. Environment: copy deploy/staging.env.example to ${CMS_ROOT}/shared/.env and fill it in.

5. First deploy:
   sudo -u ${APP_USER} -H bash ${CMS_ROOT}/repo/deploy/deploy.sh
EOF
