#!/bin/bash
# DocFast Infrastructure Setup Script
# Provisions a fresh Ubuntu/Debian server with all required services
# Run as root: ./setup.sh

set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1"
    exit 1
}

# Check if running as root
if [[ $EUID -ne 0 ]]; then
   error "This script must be run as root"
fi

# Domain and user configuration
DOMAIN="${DOMAIN:-docfast.dev}"
APP_USER="${APP_USER:-docfast}"
BACKUP_DIR="/opt/docfast-backups"
INSTALL_DIR="/opt/docfast"

log "Setting up DocFast infrastructure for domain: $DOMAIN"

# Update system
log "Updating system packages..."
apt update && apt upgrade -y

# Install required packages
log "Installing required packages..."
apt install -y \
    nginx \
    postfix \
    opendkim \
    opendkim-tools \
    certbot \
    python3-certbot-nginx \
    ufw \
    docker.io \
    docker-compose-plugin \
    git \
    sqlite3 \
    curl \
    wget \
    unzip \
    htop \
    postgresql \
    postgresql-contrib

# Enable and start services
log "Enabling services..."
systemctl enable nginx postfix opendkim docker postgresql
systemctl start nginx postfix opendkim docker postgresql

# Create application user
if ! id "$APP_USER" &>/dev/null; then
    log "Creating application user: $APP_USER"
    useradd -r -m -s /bin/bash "$APP_USER"
fi

# Add user to docker group
usermod -aG docker "$APP_USER"

# Setup UFW firewall
log "Configuring firewall..."
ufw --force enable
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow from 172.16.0.0/12 to any port 25 comment "Docker SMTP relay"
ufw allow from 172.16.0.0/12 to any port 5432 comment "Docker PostgreSQL"

# Setup PostgreSQL
log "Configuring PostgreSQL..."
sudo -u postgres createuser -D -A -P docfast || true  # -P prompts for password
sudo -u postgres createdb -O docfast docfast || true

# Update PostgreSQL to allow Docker connections
PG_VERSION=$(ls /etc/postgresql/)
PG_CONF="/etc/postgresql/$PG_VERSION/main/postgresql.conf"
PG_HBA="/etc/postgresql/$PG_VERSION/main/pg_hba.conf"

# Backup original configs
cp "$PG_CONF" "$PG_CONF.backup" || true
cp "$PG_HBA" "$PG_HBA.backup" || true

# Allow connections from Docker networks
if ! grep -q "listen_addresses = '*'" "$PG_CONF"; then
    sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" "$PG_CONF"
fi

# Allow Docker networks to connect
if ! grep -q "172.17.0.0/16" "$PG_HBA"; then
    echo "host docfast docfast 172.17.0.0/16 md5" >> "$PG_HBA"
    echo "host docfast docfast 172.18.0.0/16 md5" >> "$PG_HBA"
fi

systemctl restart postgresql

# Setup OpenDKIM
log "Configuring OpenDKIM..."
mkdir -p /etc/opendkim/keys/"$DOMAIN"
chown -R opendkim:opendkim /etc/opendkim/keys

# Generate DKIM keys if they don't exist
if [[ ! -f /etc/opendkim/keys/"$DOMAIN"/mail.private ]]; then
    log "Generating DKIM keys..."
    cd /etc/opendkim/keys/"$DOMAIN"
    opendkim-genkey -s mail -d "$DOMAIN"
    chown opendkim:opendkim mail.private mail.txt
    chmod 600 mail.private
fi

# Copy configuration files
log "Installing configuration files..."
cp nginx/"$DOMAIN" /etc/nginx/sites-available/"$DOMAIN" || warn "Nginx config not found, you'll need to configure manually"
cp postfix/main.cf /etc/postfix/main.cf || warn "Postfix config not found, you'll need to configure manually"
cp postfix/opendkim.conf /etc/opendkim.conf || warn "OpenDKIM config not found, you'll need to configure manually"
cp postfix/TrustedHosts /etc/opendkim/TrustedHosts || warn "TrustedHosts config not found, you'll need to configure manually"

# Enable nginx site
if [[ -f /etc/nginx/sites-available/"$DOMAIN" ]]; then
    ln -sf /etc/nginx/sites-available/"$DOMAIN" /etc/nginx/sites-enabled/
    rm -f /etc/nginx/sites-enabled/default
    nginx -t && systemctl reload nginx
fi

# Update configurations with actual domain
log "Updating configuration files..."
sed -i "s/docfast\.dev/$DOMAIN/g" /etc/nginx/sites-available/"$DOMAIN" 2>/dev/null || true
sed -i "s/docfast\.dev/$DOMAIN/g" /etc/postfix/main.cf 2>/dev/null || true
sed -i "s/docfast\.dev/$DOMAIN/g" /etc/opendkim.conf 2>/dev/null || true

# Restart services with new configs
systemctl restart postfix opendkim

# Install BorgBackup
log "Installing BorgBackup..."
apt install -y borgbackup

# Setup backup directories and scripts
log "Setting up backup system..."
mkdir -p "$BACKUP_DIR"
mkdir -p /opt/borg-backups

# Copy backup scripts
cp ../scripts/docfast-backup.sh /opt/docfast-backup.sh || warn "SQLite backup script not found"
cp ../scripts/borg-backup.sh /opt/borg-backup.sh || warn "Borg backup script not found"
cp ../scripts/borg-restore.sh /opt/borg-restore.sh || warn "Borg restore script not found"
cp ../scripts/rollback.sh /opt/rollback.sh || warn "Rollback script not found"

chmod +x /opt/docfast-backup.sh /opt/borg-backup.sh /opt/borg-restore.sh /opt/rollback.sh

# Add backup cron jobs
if ! crontab -l 2>/dev/null | grep -q docfast-backup; then
    (crontab -l 2>/dev/null; echo "0 */6 * * * /opt/docfast-backup.sh >> /var/log/docfast-backup.log 2>&1") | crontab -
fi

if ! crontab -l 2>/dev/null | grep -q borg-backup; then
    (crontab -l 2>/dev/null; echo "0 3 * * * /opt/borg-backup.sh >> /var/log/borg-backup.log 2>&1") | crontab -
fi

# Setup application directory
log "Setting up application directory..."
mkdir -p "$INSTALL_DIR"
chown "$APP_USER":"$APP_USER" "$INSTALL_DIR"

# Install Docker Compose
if ! command -v docker-compose &> /dev/null; then
    log "Installing docker-compose..."
    COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4)
    curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
fi

log "Base infrastructure setup complete!"
echo
log "Next steps:"
echo "1. Configure DNS A record for $DOMAIN to point to this server"
echo "2. Generate SSL certificates: certbot --nginx -d $DOMAIN"
echo "3. Copy your .env file with secrets to $INSTALL_DIR/.env"
echo "4. Copy your docker-compose.yml to $INSTALL_DIR/"
echo "5. Build and start the application:"
echo "   cd $INSTALL_DIR"
echo "   docker-compose up -d"
echo
warn "Remember to:"
echo "- Set up your DKIM DNS record (see /etc/opendkim/keys/$DOMAIN/mail.txt)"
echo "- Configure Stripe webhooks"
echo "- Set up monitoring/alerting"
echo "- Test email delivery"