#!/usr/bin/env bash
# ==============================================================================
# GoodGo Platform — VPS Server Setup Script
# Target: VelikSV01 (185.225.232.65) — Ubuntu 22.04+
#
# Usage:
#   scp infra/server-setup.sh ubuntu@185.225.232.65:~/
#   ssh ubuntu@185.225.232.65 'chmod +x ~/server-setup.sh && sudo ~/server-setup.sh'
# ==============================================================================

set -euo pipefail

# ── Colors ────────────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log()  { echo -e "${GREEN}[SETUP]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err()  { echo -e "${RED}[ERROR]${NC} $*" >&2; }

# ── Pre-flight checks ────────────────────────────────────────────────────────
if [ "$(id -u)" -ne 0 ]; then
  err "This script must be run as root (sudo)."
  exit 1
fi

DEPLOY_USER="${DEPLOY_USER:-ubuntu}"
DEPLOY_DIR="/home/${DEPLOY_USER}/goodgo"

log "Starting GoodGo Platform server setup..."
log "Deploy user: ${DEPLOY_USER}"
log "Deploy dir:  ${DEPLOY_DIR}"

# ── 1. System Updates ─────────────────────────────────────────────────────────
log "Updating system packages..."
apt-get update -qq
apt-get upgrade -y -qq

# ── 2. Install Essential Packages ─────────────────────────────────────────────
log "Installing essential packages..."
apt-get install -y -qq \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg \
  lsb-release \
  software-properties-common \
  git \
  jq \
  htop \
  unzip \
  fail2ban \
  ufw \
  logrotate

# ── 3. Install Docker Engine ─────────────────────────────────────────────────
if command -v docker &>/dev/null; then
  log "Docker already installed: $(docker --version)"
else
  log "Installing Docker Engine..."
  curl -fsSL https://get.docker.com | sh

  # Add deploy user to docker group
  usermod -aG docker "${DEPLOY_USER}"
  log "Docker installed: $(docker --version)"
fi

# Ensure Docker starts on boot
systemctl enable docker
systemctl start docker

# ── 4. Install Docker Compose v2 (plugin) ────────────────────────────────────
if docker compose version &>/dev/null; then
  log "Docker Compose already installed: $(docker compose version --short)"
else
  log "Installing Docker Compose v2 plugin..."
  DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r .tag_name)
  mkdir -p /usr/local/lib/docker/cli-plugins
  curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-$(uname -m)" \
    -o /usr/local/lib/docker/cli-plugins/docker-compose
  chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
  log "Docker Compose installed: $(docker compose version --short)"
fi

# ── 5. Install Nginx ──────────────────────────────────────────────────────────
if command -v nginx &>/dev/null; then
  log "Nginx already installed: $(nginx -v 2>&1)"
else
  log "Installing Nginx..."
  apt-get install -y -qq nginx
  log "Nginx installed: $(nginx -v 2>&1)"
fi

systemctl enable nginx
systemctl start nginx

# ── 6. Configure Firewall (ufw) ──────────────────────────────────────────────
log "Configuring firewall (ufw)..."
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp comment 'SSH'
ufw allow 80/tcp comment 'HTTP — redirect to HTTPS'
ufw allow 443/tcp comment 'HTTPS'
ufw --force enable
log "Firewall configured. Active rules:"
ufw status verbose

# ── 7. Configure fail2ban ─────────────────────────────────────────────────────
log "Configuring fail2ban..."
cat > /etc/fail2ban/jail.local << 'F2B_CONF'
[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
maxretry = 3

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true
F2B_CONF

systemctl enable fail2ban
systemctl restart fail2ban
log "fail2ban configured and running."

# ── 8. Create Directory Structure ────────────────────────────────────────────
log "Creating deployment directory structure..."
mkdir -p "${DEPLOY_DIR}"/{monitoring/{prometheus,grafana/{provisioning,dashboards},loki,promtail,alertmanager},scripts/backup,infra/pgbouncer}
chown -R "${DEPLOY_USER}:${DEPLOY_USER}" "${DEPLOY_DIR}"
log "Directory structure created at ${DEPLOY_DIR}"

# ── 9. Create SSL Directory ──────────────────────────────────────────────────
log "Creating SSL certificate directory..."
mkdir -p /etc/ssl/goodgo
chmod 700 /etc/ssl/goodgo
log "SSL directory: /etc/ssl/goodgo (place origin.pem + origin-key.pem here)"

# ── 10. Nginx Base Configuration ─────────────────────────────────────────────
log "Creating Nginx base configuration..."

# Create sites-available/sites-enabled structure if not exists
mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled

# Check if nginx.conf already includes sites-enabled
if ! grep -q 'sites-enabled' /etc/nginx/nginx.conf; then
  warn "Adding 'include sites-enabled' to nginx.conf"
  sed -i '/http {/a \    include /etc/nginx/sites-enabled/*;' /etc/nginx/nginx.conf
fi

# Remove default site
rm -f /etc/nginx/sites-enabled/default

# Nginx performance tuning
cat > /etc/nginx/conf.d/performance.conf << 'NGINX_PERF'
# GoodGo Platform — Nginx Performance Tuning
# Rate limiting zone (used by API vhost)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/s;

# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

# Proxy settings
proxy_connect_timeout 60s;
proxy_send_timeout    60s;
proxy_read_timeout    60s;
proxy_buffers         32 8k;

# Security
server_tokens off;
NGINX_PERF

nginx -t && systemctl reload nginx
log "Nginx base configuration ready."

# ── 11. Docker Log Rotation ──────────────────────────────────────────────────
log "Configuring Docker log rotation..."
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'DOCKER_LOG'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  },
  "storage-driver": "overlay2"
}
DOCKER_LOG

systemctl restart docker
log "Docker log rotation configured."

# ── 12. Swap (if <4GB RAM) ───────────────────────────────────────────────────
TOTAL_MEM=$(free -m | awk '/^Mem:/{print $2}')
if [ "$TOTAL_MEM" -lt 4096 ]; then
  if [ ! -f /swapfile ]; then
    log "Low RAM (${TOTAL_MEM}MB). Creating 4GB swap..."
    fallocate -l 4G /swapfile
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile
    echo '/swapfile none swap sw 0 0' >> /etc/fstab
    log "Swap created and enabled."
  else
    log "Swap already exists."
  fi
else
  log "RAM: ${TOTAL_MEM}MB — swap not needed."
fi

# ── 13. Kernel Tuning (for Docker/PostgreSQL) ────────────────────────────────
log "Applying kernel tuning..."
cat >> /etc/sysctl.conf << 'SYSCTL'

# GoodGo — Docker + PostgreSQL tuning
vm.overcommit_memory = 1
vm.swappiness = 10
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 2097152
SYSCTL

sysctl -p >/dev/null 2>&1 || true
log "Kernel parameters tuned."

# ── Summary ──────────────────────────────────────────────────────────────────
echo ""
log "=========================================="
log " Server setup complete!"
log "=========================================="
log ""
log " Next steps:"
log "  1. Place Cloudflare Origin Certificate:"
log "     /etc/ssl/goodgo/origin.pem"
log "     /etc/ssl/goodgo/origin-key.pem"
log ""
log "  2. Copy Nginx vhost configs to:"
log "     /etc/nginx/sites-available/"
log "     Then symlink to /etc/nginx/sites-enabled/"
log ""
log "  3. Create .env file at:"
log "     ${DEPLOY_DIR}/.env"
log ""
log "  4. Login to GHCR:"
log "     docker login ghcr.io"
log ""
log "  5. Deploy:"
log "     cd ${DEPLOY_DIR}"
log "     docker compose -f docker-compose.prod.yml up -d"
log "=========================================="
