#!/bin/bash
#
# LetsBe Server Setup Script
# This script sets up the server and deploys selected tools.
#
# Usage:
#   ./setup.sh --tools "all" --domain "example.com"
#   ./setup.sh --tools "portainer,n8n,baserow" --domain "example.com"
#   ./setup.sh --tools "1,2,3"
#   ./setup.sh                    # Foundation only, no tools deployed
#
# Arguments:
#   --tools         Comma-separated list of tools to deploy, "all", or tool numbers
#   --domain        Domain name for SSL email (administrator@domain)
#   --skip-ssl      Skip SSL certificate setup (useful for testing)
#   --admin-user    Admin username to create with SSH key access
#   --admin-ssh-key Public SSH key for the admin user
#

set -euo pipefail

# Prevent interactive prompts during apt install
export DEBIAN_FRONTEND=noninteractive

# =============================================================================
# ARGUMENT PARSING
# =============================================================================

TOOLS_TO_DEPLOY=""
SKIP_SSL=false
ROOT_SSL=false
DOMAIN=""

# Docker registry authentication (optional)
DOCKER_USER=""
DOCKER_TOKEN=""
DOCKER_REGISTRY=""

# Gitea registry authentication (for private images from code.letsbe.solutions)
GITEA_REGISTRY=""
GITEA_USER=""
GITEA_TOKEN=""

# Admin user setup (optional - replaces hardcoded user)
ADMIN_USER=""
ADMIN_SSH_KEY=""

while [[ $# -gt 0 ]]; do
    case $1 in
        --tools)
            TOOLS_TO_DEPLOY="$2"
            shift 2
            ;;
        --domain)
            DOMAIN="$2"
            shift 2
            ;;
        --skip-ssl)
            SKIP_SSL=true
            shift
            ;;
        --root-ssl)
            ROOT_SSL=true
            shift
            ;;
        --docker-user)
            DOCKER_USER="$2"
            shift 2
            ;;
        --docker-token)
            DOCKER_TOKEN="$2"
            shift 2
            ;;
        --docker-registry)
            DOCKER_REGISTRY="$2"
            shift 2
            ;;
        --gitea-registry)
            GITEA_REGISTRY="$2"
            shift 2
            ;;
        --gitea-user)
            GITEA_USER="$2"
            shift 2
            ;;
        --gitea-token)
            GITEA_TOKEN="$2"
            shift 2
            ;;
        --admin-user)
            ADMIN_USER="$2"
            shift 2
            ;;
        --admin-ssh-key)
            ADMIN_SSH_KEY="$2"
            shift 2
            ;;
        --help|-h)
            echo "Usage: $0 [--tools \"tool1,tool2,...\"|\"all\"] [--domain DOMAIN] [--skip-ssl] [--root-ssl]"
            echo ""
            echo "Options:"
            echo "  --tools       Comma-separated list of tools, 'all', or tool numbers"
            echo "  --domain      Domain name for SSL email (administrator@domain)"
            echo "  --skip-ssl    Skip SSL certificate setup"
            echo "  --root-ssl    Include root domain in SSL certificate"
            echo "  --docker-user Docker registry username (optional)"
            echo "  --docker-token Docker registry password/token (optional)"
            echo "  --docker-registry Docker registry URL (optional, defaults to Docker Hub)"
            echo "  --admin-user     Admin username to create with SSH key access"
            echo "  --admin-ssh-key  Public SSH key for the admin user"
            echo ""
            echo "Examples:"
            echo "  $0 --tools \"all\" --domain \"example.com\""
            echo "  $0 --tools \"portainer,n8n,baserow\""
            echo "  $0 --tools \"1,5,10\""
            echo "  $0  # Foundation only"
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            echo "Use --help for usage information"
            exit 1
            ;;
    esac
done

echo "=== LetsBe Server Setup ==="
echo ""

# =============================================================================
# PACKAGE INSTALLATION
# =============================================================================

echo "[1/10] Installing system packages..."
sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential net-tools tree wget jq nano curl htop ufw fail2ban unattended-upgrades apt-listchanges apticron git gnupg ca-certificates apache2-utils acl certbot python3-certbot-nginx rsync rclone s3cmd zip sudo iptables htop dstat openssl

# =============================================================================
# DOCKER INSTALLATION
# =============================================================================

echo "[2/10] Installing Docker..."
sudo install -m 0755 -d /etc/apt/keyrings
# Use --batch and --yes for non-interactive gpg (required for nohup/background execution)
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /tmp/docker.gpg
sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg /tmp/docker.gpg
rm -f /tmp/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
sudo echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable docker

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod 755 /usr/local/bin/docker-compose

# Docker registry login (optional - for private registries or to bypass rate limits)
if [[ -n "$DOCKER_USER" && -n "$DOCKER_TOKEN" ]]; then
    if [[ -n "$DOCKER_REGISTRY" ]]; then
        echo "Logging into Docker registry: $DOCKER_REGISTRY..."
        echo "$DOCKER_TOKEN" | docker login -u "$DOCKER_USER" --password-stdin "$DOCKER_REGISTRY"
    else
        echo "Logging into Docker Hub..."
        echo "$DOCKER_TOKEN" | docker login -u "$DOCKER_USER" --password-stdin
    fi
fi

# Gitea registry login (for private images from code.letsbe.solutions)
if [[ -n "$GITEA_REGISTRY" && -n "$GITEA_USER" && -n "$GITEA_TOKEN" ]]; then
    echo "Logging into Gitea registry: $GITEA_REGISTRY..."
    echo "$GITEA_TOKEN" | docker login -u "$GITEA_USER" --password-stdin "$GITEA_REGISTRY"
fi

# =============================================================================
# DISABLE CONFLICTING SERVICES
# =============================================================================

echo "[3/10] Disabling conflicting services..."
sudo systemctl stop exim4 2>/dev/null || true
sudo systemctl disable exim4 2>/dev/null || true

sudo systemctl stop apache2 2>/dev/null || true
sudo systemctl disable apache2 2>/dev/null || true
sudo apt remove -y apache2 2>/dev/null || true

# =============================================================================
# NGINX INSTALLATION & CONFIGURATION
# =============================================================================

echo "[4/10] Installing and configuring nginx..."
sudo apt install -y nginx
sudo systemctl enable nginx

sudo rm -f /etc/nginx/sites-enabled/default

openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /etc/nginx/placeholder.key -out /etc/nginx/placeholder.crt

cat <<EOF > /etc/nginx/conf.d/fallback.conf
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444;
}

server {
    listen 443 ssl default_server;
    server_name _;
    return 444;

    ssl_certificate /etc/nginx/placeholder.crt;
    ssl_certificate_key /etc/nginx/placeholder.key;
}
EOF

sudo systemctl restart nginx

# =============================================================================
# FIREWALL CONFIGURATION
# =============================================================================

echo "[5/10] Configuring UFW firewall..."
ufw allow 22
ufw allow 22022
ufw allow 80
ufw allow 443

# Open mail ports only if Poste mail server is being deployed
if [[ "$TOOLS_TO_DEPLOY" == *"poste"* || "$TOOLS_TO_DEPLOY" == "all" ]]; then
    echo "Opening mail ports for Poste..."
    ufw allow 25
    ufw allow 587
    ufw allow 143
    ufw allow 110
    ufw allow 4190
    ufw allow 465
    ufw allow 993
    ufw allow 995
fi

ufw --force enable

# =============================================================================
# ADMIN USER SETUP
# =============================================================================

if [[ -n "$ADMIN_USER" && -n "$ADMIN_SSH_KEY" ]]; then
    echo "[6/10] Configuring admin user '$ADMIN_USER'..."

    if ! id -u "$ADMIN_USER" > /dev/null 2>&1; then
        echo "User $ADMIN_USER does not exist, will be created."
        useradd -m -s /bin/bash "$ADMIN_USER"
    fi

    mkdir -p /home/$ADMIN_USER/.ssh
    chmod 700 /home/$ADMIN_USER/.ssh

    echo "$ADMIN_SSH_KEY" >> /home/$ADMIN_USER/.ssh/authorized_keys
    chmod 600 /home/$ADMIN_USER/.ssh/authorized_keys
    chown -R $ADMIN_USER:$ADMIN_USER /home/$ADMIN_USER/.ssh

    usermod -aG docker "$ADMIN_USER"

    echo "Public key was added for user $ADMIN_USER."
else
    echo "[6/10] Skipping admin user setup (no --admin-user and --admin-ssh-key provided)"
fi

# =============================================================================
# SSH SECURITY HARDENING
# =============================================================================

echo "[7/10] Hardening SSH configuration..."
cat <<EOF > /etc/ssh/sshd_config
Include /etc/ssh/sshd_config.d/*.conf

Port 22022
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

SyslogFacility AUTH
LogLevel VERBOSE

LoginGraceTime 2m
PermitRootLogin prohibit-password
#StrictModes yes
MaxAuthTries 6
MaxSessions 10

PasswordAuthentication no
PermitEmptyPasswords no

ChallengeResponseAuthentication no

UsePAM yes

X11Forwarding yes
PrintMotd no
PrintLastLog yes

AcceptEnv LANG LC_*

Subsystem	sftp	/usr/lib/openssh/sftp-server

UsePrivilegeSeparation sandbox
AuthenticationMethods publickey
EOF

# NOTE: SSH restart moved to end of script to keep connection alive

# =============================================================================
# AUTOMATIC SECURITY UPDATES
# =============================================================================

echo "[8/10] Configuring automatic security updates..."
cat <<EOF > /etc/apt/apt.conf.d/20auto-upgrades
// Enable the update/upgrade script (0=disable)
APT::Periodic::Enable "1";

// Do "apt-get update" automatically every n-days (0=disable)
APT::Periodic::Update-Package-Lists "1";

// Do "apt-get upgrade --download-only" every n-days (0=disable)
APT::Periodic::Download-Upgradeable-Packages "1";

// Do "apt-get autoclean" every n-days (0=disable)
APT::Periodic::AutocleanInterval "7";

// Send report mail to root
//     0:  no report             (or null string)
//     1:  progress report       (actually any string)
//     2:  + command outputs     (remove -qq, remove 2>/dev/null, add -d)
APT::Periodic::Unattended-Upgrade "1";

// Automatically upgrade packages from these
Unattended-Upgrade::Origins-Pattern {
//      "o=Debian,a=stable";
//      "o=Debian,a=stable-updates";
      "origin=Debian,codename=\${distro_codename},label=Debian-Security";
};

// You can specify your own packages to NOT automatically upgrade here
Unattended-Upgrade::Package-Blacklist {
};

// Run dpkg --force-confold --configure -a if a unclean dpkg state is detected to true to ensure that updates get installed even when the system got interrupted during a previous run
Unattended-Upgrade::AutoFixInterruptedDpkg "true";

// Perform the upgrade when the machine is running because we wont be shutting our server down often
Unattended-Upgrade::InstallOnShutdown "false";

// Send an email to this address with information about the packages upgraded.
Unattended-Upgrade::Mail "administrator@letsbe.biz";

// Always send an e-mail
Unattended-Upgrade::MailOnlyOnError "true";

// Remove all unused dependencies after the upgrade has finished
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// Remove any new unused dependencies after the upgrade has finished
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

// Automatically reboot WITHOUT CONFIRMATION if the file /var/run/reboot-required is found after the upgrade.
Unattended-Upgrade::Automatic-Reboot "false";

// Automatically reboot even if users are logged in.
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
EOF

# =============================================================================
# BACKUP SCRIPT & CRON
# =============================================================================

echo "Setting up backup script and cron..."
chmod 750 /opt/letsbe/scripts/backups.sh 2>/dev/null || true
chmod 750 /opt/letsbe/scripts/restore.sh 2>/dev/null || true
mkdir -p /root/.config/rclone
mkdir -p /opt/letsbe/logs

# Install backup cron non-interactively (daily at 2am)
BACKUP_CRON="0 2 * * * /bin/bash /opt/letsbe/scripts/backups.sh >> /opt/letsbe/logs/backup.log 2>&1"
( crontab -l 2>/dev/null | grep -v "backups.sh"; echo "$BACKUP_CRON" ) | crontab -
echo "Backup cron installed (daily at 2:00 AM)"

# =============================================================================
# TOOL DEPLOYMENT
# =============================================================================

echo "[9/10] Deploying tools..."

# Get list of available tools
mapfile -t available_tools < <(ls /opt/letsbe/stacks/*/docker-compose.yml 2>/dev/null | xargs -I {} dirname {} | xargs -I {} basename {})

if [[ -z "$TOOLS_TO_DEPLOY" ]]; then
    echo "No tools specified. Skipping tool deployment."
    echo "Available tools: ${available_tools[*]}"
    echo "Use --tools to deploy tools later."
else
    # Determine which tools to deploy
    declare -a tools_list=()

    if [[ "$TOOLS_TO_DEPLOY" == "all" || "$TOOLS_TO_DEPLOY" == "a" ]]; then
        tools_list=("${available_tools[@]}")
    else
        # Parse comma-separated list
        IFS=',' read -ra requested_tools <<< "$TOOLS_TO_DEPLOY"
        for tool in "${requested_tools[@]}"; do
            tool=$(echo "$tool" | xargs)  # Trim whitespace

            # Check if it's a number (index)
            if [[ "$tool" =~ ^[0-9]+$ ]]; then
                idx=$((tool - 1))
                if [[ $idx -ge 0 && $idx -lt ${#available_tools[@]} ]]; then
                    tools_list+=("${available_tools[$idx]}")
                else
                    echo "Warning: Tool index $tool out of range, skipping."
                fi
            else
                # It's a tool name
                if [[ " ${available_tools[*]} " =~ " ${tool} " ]]; then
                    tools_list+=("$tool")
                else
                    echo "Warning: Tool '$tool' not found, skipping."
                fi
            fi
        done
    fi

    # Ensure orchestrator is FIRST (creates network that sysadmin needs)
    if [[ -f "/opt/letsbe/stacks/orchestrator/docker-compose.yml" ]]; then
        # Remove orchestrator from current position if present
        declare -a new_list=()
        for tool in "${tools_list[@]}"; do
            if [[ "$tool" != "orchestrator" ]]; then
                new_list+=("$tool")
            fi
        done
        # Prepend orchestrator to front
        tools_list=("orchestrator" "${new_list[@]}")
        echo "Orchestrator moved to front (creates network for sysadmin)"
    fi

    echo "Deploying tools: ${tools_list[*]}"

    # Track deployed tools for SSL setup
    DEPLOYED_TOOLS=()

    for tool_name in "${tools_list[@]}"; do
        compose_file="/opt/letsbe/stacks/${tool_name}/docker-compose.yml"

        if [[ -f "$compose_file" ]]; then
            # Copy .env file to centralized env directory if it exists
            stack_env="/opt/letsbe/stacks/${tool_name}/.env"
            central_env="/opt/letsbe/env/${tool_name}.env"
            if [[ -f "$stack_env" ]]; then
                cp "$stack_env" "$central_env"
                chmod 600 "$central_env"
                echo "Copied env file for $tool_name"
            fi

            # Tool-specific pre-deployment setup
            if [[ "$tool_name" == "nextcloud" ]]; then
                echo "Creating Nextcloud bind mount directories..."
                mkdir -p /opt/letsbe/config/nextcloud
                mkdir -p /opt/letsbe/data/nextcloud
                # Set appropriate ownership for www-data (uid 33 in Nextcloud container)
                chown -R 33:33 /opt/letsbe/config/nextcloud
                chown -R 33:33 /opt/letsbe/data/nextcloud
            fi

            if [[ "$tool_name" == "sysadmin" ]]; then
                echo "  Pulling latest sysadmin agent image..."
                docker-compose -f "$compose_file" pull
            fi

            echo "Starting $tool_name..."
            docker-compose -f "$compose_file" up -d

            # Tool-specific post-deployment initialization
            if [[ "$tool_name" == "portainer" ]]; then
                echo "Configuring Portainer local Docker endpoint..."

                # Get Portainer container name
                PORTAINER_CONTAINER=$(docker ps --format '{{.Names}}' | grep portainer | head -1)

                if [[ -n "$PORTAINER_CONTAINER" ]]; then
                    # Wait for Portainer to be ready
                    echo "  Waiting for Portainer to be ready..."
                    for i in {1..30}; do
                        if curl -ks https://localhost:9443/api/system/status >/dev/null 2>&1; then
                            echo "  Portainer is ready."
                            break
                        fi
                        sleep 2
                    done

                    # Read admin password from file
                    PORTAINER_PASSWORD=$(cat /opt/letsbe/env/portainer_admin_password.txt 2>/dev/null)

                    if [[ -n "$PORTAINER_PASSWORD" ]]; then
                        # Authenticate and get JWT token
                        echo "  Authenticating with Portainer..."
                        JWT_RESPONSE=$(curl -ks -X POST https://localhost:9443/api/auth \
                            -H "Content-Type: application/json" \
                            -d "{\"username\":\"admin\",\"password\":\"${PORTAINER_PASSWORD}\"}" 2>/dev/null)

                        JWT=$(echo "$JWT_RESPONSE" | grep -o '"jwt":"[^"]*"' | cut -d'"' -f4)

                        if [[ -n "$JWT" ]]; then
                            echo "  Creating local Docker endpoint..."
                            # Create local Docker socket endpoint
                            ENDPOINT_RESPONSE=$(curl -ks -X POST https://localhost:9443/api/endpoints \
                                -H "Authorization: Bearer $JWT" \
                                -H "Content-Type: multipart/form-data" \
                                -F "Name=local" \
                                -F "EndpointCreationType=1" 2>/dev/null)

                            if echo "$ENDPOINT_RESPONSE" | grep -q '"Id"'; then
                                echo "  Local Docker endpoint created successfully."
                            else
                                echo "  Warning: Endpoint creation response: $ENDPOINT_RESPONSE"
                            fi
                        else
                            echo "  Warning: Could not authenticate with Portainer"
                        fi
                    else
                        echo "  Warning: Could not read Portainer password file"
                    fi
                else
                    echo "  Warning: Could not find Portainer container"
                fi
            fi

            if [[ "$tool_name" == "chatwoot" ]]; then
                echo "Initializing Chatwoot database (pgvector + migrations)..."

                # Get the customer prefix from the container name
                CHATWOOT_POSTGRES=$(docker ps --format '{{.Names}}' | grep chatwoot-postgres | head -1)
                CHATWOOT_RAILS=$(docker ps --format '{{.Names}}' | grep chatwoot-rails | head -1)

                if [[ -n "$CHATWOOT_POSTGRES" && -n "$CHATWOOT_RAILS" ]]; then
                    # Wait for Postgres to be ready
                    echo "  Waiting for Postgres to be ready..."
                    for i in {1..30}; do
                        if docker exec "$CHATWOOT_POSTGRES" pg_isready -U chatwoot -d chatwoot_production >/dev/null 2>&1; then
                            echo "  Postgres is ready."
                            break
                        fi
                        sleep 2
                    done

                    # Create pgvector extension
                    echo "  Creating pgvector extension..."
                    docker exec "$CHATWOOT_POSTGRES" psql -U chatwoot -d chatwoot_production -c "CREATE EXTENSION IF NOT EXISTS vector;" 2>/dev/null || true

                    # Wait for Rails container to be fully up
                    echo "  Waiting for Rails container..."
                    sleep 10

                    # Run database migrations
                    echo "  Running Chatwoot database prepare..."
                    docker exec "$CHATWOOT_RAILS" bundle exec rails db:chatwoot_prepare 2>&1 || echo "  Note: db:chatwoot_prepare may have already run"

                    echo "  Chatwoot initialization complete."
                else
                    echo "  Warning: Could not find Chatwoot containers for initialization"
                fi
            fi

            # Link nginx config if exists
            nginx_conf="/opt/letsbe/nginx/${tool_name}.conf"
            if [[ -f "$nginx_conf" ]]; then
                cp "$nginx_conf" /etc/nginx/sites-available/
                ln -sf /etc/nginx/sites-available/${tool_name}.conf /etc/nginx/sites-enabled/
                echo "Nginx config linked for $tool_name"
                DEPLOYED_TOOLS+=("$tool_name")
            else
                echo "No nginx config for $tool_name (may not need one)"
            fi
        else
            echo "Warning: docker-compose.yml not found for $tool_name"
        fi
    done

    # Restart nginx to apply new configs
    systemctl restart nginx
fi

# =============================================================================
# SYSADMIN AGENT (Always deployed)
# =============================================================================

echo "[9.5/10] Deploying sysadmin agent..."

SYSADMIN_COMPOSE="/opt/letsbe/stacks/sysadmin/docker-compose.yml"
if [[ -f "$SYSADMIN_COMPOSE" ]]; then
    # Check if sysadmin is already running
    if docker ps --format '{{.Names}}' | grep -q "agent$"; then
        echo "  Sysadmin agent already running, updating..."
    fi

    echo "  Pulling latest sysadmin agent image..."
    docker-compose -f "$SYSADMIN_COMPOSE" pull

    echo "  Starting sysadmin agent..."
    docker-compose -f "$SYSADMIN_COMPOSE" up -d

    echo "  Sysadmin agent deployed successfully."
else
    echo "Warning: Sysadmin docker-compose.yml not found at $SYSADMIN_COMPOSE"
fi

# =============================================================================
# LOCAL ORCHESTRATOR BOOTSTRAP (License Validation + Agent Registration)
# =============================================================================

echo "[9.6/10] Running local orchestrator bootstrap..."

BOOTSTRAP_SCRIPT="/opt/letsbe/scripts/local_bootstrap.sh"
CREDENTIALS_FILE="/opt/letsbe/env/credentials.env"

if [[ -f "$BOOTSTRAP_SCRIPT" && -f "$CREDENTIALS_FILE" ]]; then
    # Source credentials to get required variables
    source "$CREDENTIALS_FILE"

    echo "  Validating license and setting up local orchestrator..."
    echo "  Instance ID: ${INSTANCE_ID:-unknown}"
    echo "  Hub URL: ${HUB_URL:-unknown}"

    # Run bootstrap script with required environment variables
    HUB_URL="${HUB_URL}" \
    LICENSE_KEY="${LICENSE_KEY}" \
    INSTANCE_ID="${INSTANCE_ID}" \
    ORCHESTRATOR_URL="http://localhost:8100" \
    ADMIN_API_KEY="${ADMIN_API_KEY}" \
    CUSTOMER="$(echo ${INSTANCE_ID} | sed 's/-orchestrator$//')" \
    CREDENTIALS_DIR="/opt/letsbe/env" \
    bash "$BOOTSTRAP_SCRIPT"

    BOOTSTRAP_EXIT=$?

    if [[ $BOOTSTRAP_EXIT -ne 0 ]]; then
        echo ""
        echo "=============================================="
        echo "  BOOTSTRAP FAILED"
        echo "=============================================="
        echo ""
        echo "License validation or agent registration failed."
        echo "Check the error messages above for details."
        echo ""
        echo "Common issues:"
        echo "  - Invalid license_key in config.json"
        echo "  - Network connectivity to Hub (${HUB_URL})"
        echo "  - Instance not registered in LetsBe Hub"
        echo ""
        echo "The stack has been deployed but is NOT properly configured."
        echo "Please fix the issue and re-run: bash /opt/letsbe/scripts/local_bootstrap.sh"
        echo "=============================================="
        # Don't exit - let the rest of setup complete, but warn
    else
        echo "  Bootstrap completed successfully!"
        echo "  Agent should register with local orchestrator within 30 seconds."
    fi
else
    if [[ ! -f "$BOOTSTRAP_SCRIPT" ]]; then
        echo "Warning: Bootstrap script not found at $BOOTSTRAP_SCRIPT"
    fi
    if [[ ! -f "$CREDENTIALS_FILE" ]]; then
        echo "Warning: Credentials file not found at $CREDENTIALS_FILE"
        echo "Run env_setup.sh first to generate credentials."
    fi
fi

# Collect domains from deployed tools' nginx configs (for SSL)
SSL_DOMAINS=()
if [[ ${#DEPLOYED_TOOLS[@]} -gt 0 ]]; then
    for tool_name in "${DEPLOYED_TOOLS[@]}"; do
        tool_conf="/etc/nginx/sites-enabled/${tool_name}.conf"
        if [[ -f "$tool_conf" ]]; then
            # Extract server_name values (excluding placeholders and _)
            while IFS= read -r domain; do
                if [[ -n "$domain" && "$domain" != "_" && ! "$domain" =~ \{\{ ]]; then
                    SSL_DOMAINS+=("$domain")
                fi
            done < <(grep -h "server_name" "$tool_conf" 2>/dev/null | awk '{print $2}' | tr -d ';' | sort -u)
        fi
    done
fi

# =============================================================================
# SSL CERTIFICATE SETUP
# =============================================================================

echo "[10/10] Setting up SSL certificates..."

# NOTE: Certbot cron disabled - crontab hangs in non-interactive mode
# Certbot installs its own systemd timer, so manual cron not needed
echo "Certbot renewal handled by systemd timer (certbot.timer)"

if [[ "$SKIP_SSL" == "true" ]]; then
    echo "Skipping SSL setup (--skip-ssl flag set)"
elif [[ ${#SSL_DOMAINS[@]} -eq 0 ]]; then
    echo "No deployed tools with valid domains found."
    echo "Skipping SSL setup. Either:"
    echo "  - No tools were deployed, or"
    echo "  - Templates not replaced (run env_setup.sh first with --domain parameter)"
    echo "To manually setup SSL later: certbot --nginx -d yourdomain.com"
else
    # Remove duplicates from SSL_DOMAINS
    SSL_DOMAINS=($(printf '%s\n' "${SSL_DOMAINS[@]}" | sort -u))

    # Add root domain if --root-ssl flag is set
    if [[ "$ROOT_SSL" == "true" && -n "$DOMAIN" ]]; then
        # Check if root domain is not already in the list
        if [[ ! " ${SSL_DOMAINS[*]} " =~ " ${DOMAIN} " ]]; then
            SSL_DOMAINS+=("$DOMAIN")
            echo "Including root domain: $DOMAIN"
        fi
    fi

    echo "----"
    echo "Setting up SSL certificates for deployed tools:"
    for domain in "${SSL_DOMAINS[@]}"; do
        echo "  - $domain"
    done
    echo ""
    echo "Make sure DNS entries point to this server IP before proceeding."

    # Derive email from domain parameter or use default
    if [[ -n "$DOMAIN" ]]; then
        SSL_EMAIL="administrator@${DOMAIN}"
    else
        # Try to extract base domain from first SSL domain
        FIRST_DOMAIN="${SSL_DOMAINS[0]}"
        # Extract base domain (remove subdomain)
        BASE_DOMAIN=$(echo "$FIRST_DOMAIN" | awk -F. '{if(NF>2) print $(NF-1)"."$NF; else print $0}')
        SSL_EMAIL="administrator@${BASE_DOMAIN}"
    fi

    echo "Using email: $SSL_EMAIL"

    # Build domain arguments for certbot
    DOMAIN_ARGS=""
    for domain in "${SSL_DOMAINS[@]}"; do
        DOMAIN_ARGS="$DOMAIN_ARGS -d $domain"
    done

    # Run certbot non-interactively with specific domains
    sudo certbot --nginx \
        --non-interactive \
        --agree-tos \
        --email "$SSL_EMAIL" \
        --redirect \
        $DOMAIN_ARGS \
        || echo "Certbot completed (some domains may have failed - check DNS)"
fi

# =============================================================================
# COMPLETION SUMMARY
# =============================================================================

echo ""
echo "----"
echo "Configured domains:"
for conf_file in /etc/nginx/sites-enabled/*.conf; do
    if [[ -f "$conf_file" ]]; then
        server_names=$(grep -E "^\s*server_name\s+" "$conf_file" 2>/dev/null | awk '{print $2}' | tr -d ';' | sort | uniq)
        for server_name in $server_names; do
            if [[ "$server_name" != "_" ]]; then
                echo "  - $server_name ($conf_file)"
            fi
        done
    fi
done

SERVER_IP=$(curl -4 -s ifconfig.co)

echo ""
echo "=============================================="
echo "  LetsBe Server Setup Complete"
echo "=============================================="
echo ""
echo "Server IP: $SERVER_IP"
echo "SSH Port: 22022"
if [[ -n "$ADMIN_USER" ]]; then
    echo "SSH User: $ADMIN_USER (key-based auth only)"
else
    echo "SSH User: root (key-based auth only, no admin user configured)"
fi
echo ""
echo "Portainer (if deployed): https://$SERVER_IP:9443"
echo ""
echo "Important:"
echo "  - Configure rclone for backups: rclone config"
echo "  - SSH port changed to 22022"
if [[ -n "$ADMIN_USER" ]]; then
    echo "  - User '$ADMIN_USER' has Docker access (key in /home/$ADMIN_USER/.ssh/)"
fi
echo ""
echo "=============================================="

# =============================================================================
# MARK SETUP AS COMPLETE (before SSH restart)
# =============================================================================

touch /opt/letsbe/.setup_installed
echo "Setup marked as complete."

# =============================================================================
# RESTART SSH (MUST BE LAST - This will disconnect the session!)
# =============================================================================

echo ""
echo "Restarting SSH on port 22022... (connection will drop)"
if [[ -n "$ADMIN_USER" ]]; then
    echo "Reconnect with: ssh -i id_ed25519 -p 22022 $ADMIN_USER@$SERVER_IP"
else
    echo "Reconnect with: ssh -p 22022 root@$SERVER_IP"
fi
echo ""

# Small delay to ensure output is sent before disconnect
sleep 2

systemctl restart sshd
