#!/bin/bash
# Creates isolated site user, PHP-FPM pool, Nginx vhost, and configures SSL/QUIC.

if [ "$EUID" -ne 0 ]; then echo "Error: Run as root"; exit 1; fi
if [ "$#" -lt 4 ]; then
    echo "Usage: $0 <domain> <user> <password> <admin_email> [php_version]"
    echo "Example: $0 dieg.net dieg_admin MyPass! admin@dieg.net 8.5"
    exit 1
fi

DOMAIN=$1
SITE_USER=$2
PASS=$3
EMAIL=$4
PHP_VER=${5:-8.5}

# Convert domain to a safe pool name (replace dots with underscores)
POOL_NAME=$(echo "$DOMAIN" | tr '.' '_')

WEB_ROOT="/var/www/$DOMAIN"
FPM_SOCK="/run/php/php$PHP_VER-fpm-$POOL_NAME.sock"
POOL_DIR="/etc/php/$PHP_VER/fpm/pool.d"

if [ ! -d "$POOL_DIR" ]; then
    echo "ERROR: PHP $PHP_VER-fpm doesn't seem to be installed (no $POOL_DIR)."
    exit 1
fi

echo "==> Creating chrooted SFTP user $SITE_USER..."
if ! id -u "$SITE_USER" > /dev/null 2>&1; then
    # Create user without SSH login privileges (SFTP only)
    useradd -m -s /usr/sbin/nologin "$SITE_USER"
    echo "$SITE_USER:$PASS" | chpasswd
else
    echo "User $SITE_USER already exists. Skipping."
fi

echo "==> Creating site directories..."
mkdir -p "$WEB_ROOT/public_html"
mkdir -p "$WEB_ROOT/logs"

# The root directory must be owned by root for Chroot to work securely
chown root:root "$WEB_ROOT"
chmod 755 "$WEB_ROOT"

# Subdirectories belong to the site user
chown -R "$SITE_USER:$SITE_USER" "$WEB_ROOT/public_html"
chown -R "$SITE_USER:$SITE_USER" "$WEB_ROOT/logs"

find "$WEB_ROOT/public_html" -type d -exec chmod 755 {} \;
find "$WEB_ROOT/public_html" -type f -exec chmod 644 {} \;

echo "<?php echo 'PHP ' . PHP_VERSION . ' OK on ' . \$_SERVER['SERVER_NAME']; ?>" > "$WEB_ROOT/public_html/index.php"
chown "$SITE_USER:$SITE_USER" "$WEB_ROOT/public_html/index.php"
chmod 644 "$WEB_ROOT/public_html/index.php"

echo "==> Configuring SSHd for SFTP Chroot (if not already configured)..."
if ! grep -q "Match User $SITE_USER" /etc/ssh/sshd_config; then
    cat >> /etc/ssh/sshd_config <<EOF

# SFTP Chroot for $SITE_USER
Match User $SITE_USER
    ForceCommand internal-sftp
    PasswordAuthentication yes
    ChrootDirectory $WEB_ROOT
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no
EOF
    systemctl restart sshd
fi

echo "==> Configuring PHP-FPM pool ($PHP_VER)..."
# Tuned for 4 Cores / 4 GB RAM without swap.
cat > "$POOL_DIR/$POOL_NAME.conf" <<EOF
[$POOL_NAME]
user = $SITE_USER
group = $SITE_USER
listen = $FPM_SOCK
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = ondemand
pm.max_children = 15
pm.process_idle_timeout = 10s
pm.max_requests = 500

; Integration with our global metrics.conf
pm.status_path = /status

php_admin_value[error_log] = $WEB_ROOT/logs/php-error.log
php_admin_flag[log_errors] = on
EOF

echo "==> Creating Nginx vhost..."
cat > "/etc/nginx/sites-available/$DOMAIN" <<EOF
server {
    listen 80;
    listen [::]:80;
    server_name $DOMAIN;
    
    root $WEB_ROOT/public_html;
    index index.php index.html;

    client_max_body_size 64M;

    access_log $WEB_ROOT/logs/access.log;
    error_log $WEB_ROOT/logs/error.log;

    # Basic Security Headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # HTTP/3 (QUIC) support header. Will be uncommented after Certbot.
    # add_header Alt-Svc 'h3=":443"; ma=86400';

    # Block access to hidden files and sensitive data
    location = /wp-config.php { deny all; access_log off; log_not_found off; }
    location = /xmlrpc.php { deny all; access_log off; log_not_found off; }
    location ~ \.(log|sql|tgz|xz|tar\.gz|zip)$ { deny all; access_log off; log_not_found off; }
    location ~ /\. { deny all; access_log off; log_not_found off; }
    
    location = /robots.txt { access_log off; log_not_found off; }
    location = /favicon.ico { access_log off; log_not_found off; }

    # Allow Let's Encrypt / ACME challenge for SSL renewal
    location ~ ^/\.well-known {
        allow all;
        auth_basic off;
        access_log off;
        log_not_found off;
    }

    # Static assets caching & CORS headers
    location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|svg|svgz|webp|woff|woff2|ttf|otf|map|mjs)$ {
        add_header Access-Control-Allow-Origin "*";
        add_header Cache-Control "public, max-age=2592000, immutable";
        expires 30d;
        access_log off;
    }

    location / {
        try_files \$uri \$uri/ /index.php?\$args;
    }

    location ~ \.php$ {
        try_files \$uri =404;
        include fastcgi_params;
        fastcgi_pass unix:$FPM_SOCK;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;

        # Timeouts aligned with php.ini max_execution_time = 300
        fastcgi_send_timeout 300s;
        fastcgi_read_timeout 300s;
    }
}
EOF

ln -sf "/etc/nginx/sites-available/$DOMAIN" /etc/nginx/sites-enabled/

echo "==> Restarting PHP and Nginx before SSL..."
systemctl restart "php$PHP_VER-fpm"
nginx -t && systemctl reload nginx

echo "==> Requesting SSL certificate via Certbot..."
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "$EMAIL"

if [ $? -eq 0 ]; then
    echo "==> SSL issued successfully. Enabling HTTP/3 (QUIC)..."
    
    # Inject QUIC directives into the SSL block created by Certbot
    sed -i 's/listen 443 ssl;/listen 443 quic;\n    listen 443 ssl;/g' "/etc/nginx/sites-available/$DOMAIN"
    sed -i 's/listen \[::\]:443 ssl;/listen \[::\]:443 quic;\n    listen \[::\]:443 ssl;/g' "/etc/nginx/sites-available/$DOMAIN"
    
    # Uncomment the Alt-Svc header
    sed -i 's/# add_header Alt-Svc/add_header Alt-Svc/g' "/etc/nginx/sites-available/$DOMAIN"
    
    nginx -t && systemctl reload nginx
else
    echo "==> WARNING: Certbot failed (e.g. DNS not pointing to this IP yet)."
    echo "==> Site is active on HTTP. Run Certbot manually later."
fi

echo "=========================================="
echo "Domain: $DOMAIN"
echo "Root Path: $WEB_ROOT/public_html"
echo "SFTP Login: $SITE_USER (Chrooted securely)"
echo "FPM Pool: $POOL_NAME (Socket: $FPM_SOCK)"
echo "Status URL: curl http://127.0.0.1/status/$POOL_NAME"
echo "=========================================="
