#!/usr/bin/env bash
#
# Discourse Setup Wizard
#
# This script runs the setup wizard inside a Docker container.
#

set -e

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$DIR"

IMAGE_NAME="discourse/setup-wizard:release"

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

log_info() {
    echo -e "${GREEN}→${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}!${NC} $1"
}

log_error() {
    echo -e "${RED}✗${NC} $1"
}

# Check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "This script must be run as root. Please sudo or log in as root first."
        exit 1
    fi
}

# Check if Docker is available
check_docker() {
    if ! command -v docker &> /dev/null; then
        log_error "Docker is not installed. Please install Docker first."
        exit 1
    fi
}

# Pull the setup wizard Docker image
pull_image() {
    log_info "Checking for setup wizard image updates..."
    # if ! docker pull "$IMAGE_NAME"; then
    #     if docker image inspect "$IMAGE_NAME" &> /dev/null; then
    #         log_warn "Could not check for updates, using cached image"
    #     else
    #         log_error "Failed to pull setup wizard image"
    #         exit 1
    #     fi
    # fi
}

# Run the setup wizard container
run_wizard() {
    log_info "Starting Discourse Setup Wizard..."
    echo

    # Clean up any previous signal files
    rm -f "$DIR/.wizard_rebuild_needed"
    rm -f "$DIR/.wizard_swap_needed"

    local wizard_exit=0
    docker run -it --rm \
        --name discourse-setup-wizard \
        --network host \
        -v "$DIR:/discourse_docker" \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -e DISCOURSE_DOCKER_DIR=/discourse_docker \
        "$IMAGE_NAME" \
        "$@" < /dev/tty || wizard_exit=$?

    # Check if wizard signaled that swap creation is needed (exit code 42)
    if [[ $wizard_exit -eq 42 ]] && [[ -f "$DIR/.wizard_swap_needed" ]]; then
        rm -f "$DIR/.wizard_swap_needed"
        if create_swap; then
            log_info "Resuming setup wizard..."
            echo
            # Re-run wizard after creating swap
            run_wizard "$@"
            return $?
        else
            log_error "Failed to create swap. Please create swap manually and re-run the wizard."
            return 1
        fi
    fi

    # Check if wizard signaled that a rebuild is needed
    if [[ -f "$DIR/.wizard_rebuild_needed" ]]; then
        local app_name
        app_name=$(cat "$DIR/.wizard_rebuild_needed")
        rm -f "$DIR/.wizard_rebuild_needed"

        if [[ $wizard_exit -eq 0 ]]; then
            run_rebuild "$app_name"
        fi
    fi

    return $wizard_exit
}

# Run the launcher rebuild on the host
run_rebuild() {
    local app_name="$1"

    log_info "Rebuilding $app_name in 5 seconds (Ctrl+C to cancel)..."
    sleep 5

    log_info "Running: ./launcher rebuild $app_name"
    "$DIR/launcher" rebuild "$app_name"
}

# Create swap on the host system
create_swap() {
    log_info "Creating 2GB swapfile on host..."

    if ! install -o root -g root -m 0600 /dev/null /swapfile; then
        log_error "Failed to create swapfile"
        return 1
    fi

    if ! fallocate -l 2G /swapfile; then
        log_error "Failed to allocate swap space"
        rm -f /swapfile
        return 1
    fi

    if ! mkswap /swapfile; then
        log_error "Failed to format swapfile"
        rm -f /swapfile
        return 1
    fi

    if ! swapon /swapfile; then
        log_error "Failed to enable swap"
        rm -f /swapfile
        return 1
    fi

    echo '/swapfile swap swap auto 0 0' >> /etc/fstab
    sysctl -w vm.swappiness=10
    echo 'vm.swappiness = 10' > /etc/sysctl.d/30-discourse-swap.conf

    log_info "Swap created successfully"
    return 0
}

# Show help
show_help() {
    cat <<EOF
Discourse Setup Wizard

Usage: $0 [OPTIONS]

Options:
    --debug                 Enable debug mode (skips rebuild)
    --skip-rebuild          Skip the container rebuild after configuration
    --skip-connection-test  Skip DNS/port connectivity tests
    --help, -h              Show this help message

This script runs the interactive setup wizard to configure your Discourse
installation. It will:

  1. Check system requirements (memory, disk space, Docker)
  2. Prompt for configuration (hostname, email, SMTP settings)
  3. Generate/update containers/app.yml
  4. Optionally rebuild and start Discourse

For more information, visit: https://github.com/discourse/discourse_docker

EOF
}

# Parse arguments
WIZARD_ARGS=()

while [[ $# -gt 0 ]]; do
    case "$1" in
        --help|-h)
            show_help
            exit 0
            ;;
        *)
            WIZARD_ARGS+=("$1")
            shift
            ;;
    esac
done

# Main
check_root
check_docker
pull_image
run_wizard "${WIZARD_ARGS[@]}"
