#!/usr/bin/env bash
set -euo pipefail

APP_USER="bayline"
APP_ROOT="/var/www/bayline"
LOG_ROOT="/var/log/bayline"
PHP_VERSION="8.3"

require_root() {
  if [[ $EUID -ne 0 ]]; then
    echo "Run as root." >&2
    exit 1
  fi
}

install_packages() {
  export DEBIAN_FRONTEND=noninteractive
  apt-get update
  apt-get install -y software-properties-common curl gnupg unzip git ufw fail2ban
  add-apt-repository -y ppa:ondrej/php
  apt-get update
  apt-get install -y \
    nginx \
    "php${PHP_VERSION}-fpm" "php${PHP_VERSION}-cli" "php${PHP_VERSION}-mysql" \
    "php${PHP_VERSION}-mbstring" "php${PHP_VERSION}-xml" "php${PHP_VERSION}-curl" \
    "php${PHP_VERSION}-zip" "php${PHP_VERSION}-bcmath" "php${PHP_VERSION}-intl" \
    "php${PHP_VERSION}-redis" "php${PHP_VERSION}-gd" \
    mariadb-server redis-server supervisor certbot python3-certbot-nginx postfix
}

create_user() {
  id -u "$APP_USER" >/dev/null 2>&1 || useradd --system --shell /bin/bash --home "$APP_ROOT" "$APP_USER"
  mkdir -p "$APP_ROOT" "$LOG_ROOT"
  chown -R "$APP_USER":"$APP_USER" "$APP_ROOT" "$LOG_ROOT"
}

install_composer() {
  if ! command -v composer >/dev/null 2>&1; then
    curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php
    php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
    rm -f /tmp/composer-setup.php
  fi
}

configure_php_pool() {
  cat > "/etc/php/${PHP_VERSION}/fpm/pool.d/bayline.conf" <<POOL
[bayline]
user = ${APP_USER}
group = ${APP_USER}
listen = /run/php/php${PHP_VERSION}-fpm-bayline.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500
php_admin_value[expose_php] = Off
php_admin_value[upload_max_filesize] = 32M
php_admin_value[post_max_size] = 32M
php_admin_value[memory_limit] = 256M
php_admin_value[date.timezone] = UTC
POOL
  systemctl restart "php${PHP_VERSION}-fpm"
}

configure_firewall() {
  ufw allow OpenSSH
  ufw allow 'Nginx Full'
  ufw allow 25/tcp
  ufw --force enable
  systemctl enable --now fail2ban
}

link_configs() {
  ln -sf "${APP_ROOT}/infra/nginx/bayline.conf" /etc/nginx/sites-available/bayline.conf
  ln -sf /etc/nginx/sites-available/bayline.conf /etc/nginx/sites-enabled/bayline.conf
  rm -f /etc/nginx/sites-enabled/default
  ln -sf "${APP_ROOT}/infra/supervisor/bayline-worker.conf" /etc/supervisor/conf.d/bayline-worker.conf
  install -m 0644 "${APP_ROOT}/infra/systemd/bayline-scheduler.cron" /etc/cron.d/bayline-scheduler
  nginx -t
  systemctl reload nginx
  supervisorctl reread
  supervisorctl update
}

require_root
install_packages
create_user
install_composer
configure_php_pool
link_configs
configure_firewall

echo "Provisioning complete."
echo "Next: mysql_secure_installation, create the database and user, deploy the app to ${APP_ROOT}, then run certbot."
