#!/bin/bash

# Fluxer SSL Certificate Setup Script
# This script sets up SSL certificates for all Fluxer subdomains
# Supports both Let's Encrypt and Cloudflare DNS challenge

set -e

# Configuration
DOMAIN="st.vish.gg"
SUBDOMAINS=("api" "events" "files" "voice" "proxy")
NGINX_SSL_DIR="/etc/nginx/ssl"
NGINX_SITES_DIR="/etc/nginx/sites-available"

# 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}[INFO]${NC} $1"
}

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

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

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

# Function to install certbot
install_certbot() {
    log_info "Installing certbot..."
    apt update
    apt install -y certbot python3-certbot-nginx
}

# Function to install cloudflare plugin
install_cloudflare_plugin() {
    log_info "Installing Cloudflare DNS plugin..."
    apt install -y python3-certbot-dns-cloudflare
}

# Function to setup Let's Encrypt with HTTP challenge
setup_letsencrypt_http() {
    log_info "Setting up Let's Encrypt certificates with HTTP challenge..."

    # Build domain list
    DOMAIN_LIST="-d $DOMAIN"
    for subdomain in "${SUBDOMAINS[@]}"; do
        DOMAIN_LIST="$DOMAIN_LIST -d $subdomain.$DOMAIN"
    done

    log_info "Requesting certificates for: $DOMAIN_LIST"

    # Request certificates
    certbot --nginx $DOMAIN_LIST --non-interactive --agree-tos --email admin@$DOMAIN

    if [[ $? -eq 0 ]]; then
        log_info "✅ SSL certificates successfully generated!"
        setup_auto_renewal
    else
        log_error "❌ Failed to generate SSL certificates"
        exit 1
    fi
}

# Function to setup Let's Encrypt with Cloudflare DNS challenge
setup_letsencrypt_cloudflare() {
    local api_token="$1"

    if [[ -z "$api_token" ]]; then
        log_error "Cloudflare API token is required"
        exit 1
    fi

    log_info "Setting up Let's Encrypt certificates with Cloudflare DNS challenge..."

    # Create credentials file
    mkdir -p /etc/letsencrypt
    cat > /etc/letsencrypt/cloudflare.ini << EOF
dns_cloudflare_api_token = $api_token
EOF
    chmod 600 /etc/letsencrypt/cloudflare.ini

    # Request wildcard certificate
    certbot certonly \
        --dns-cloudflare \
        --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
        --non-interactive \
        --agree-tos \
        --email admin@$DOMAIN \
        -d $DOMAIN \
        -d "*.$DOMAIN"

    if [[ $? -eq 0 ]]; then
        log_info "✅ Wildcard SSL certificate successfully generated!"
        update_nginx_config
        setup_auto_renewal
    else
        log_error "❌ Failed to generate SSL certificate"
        exit 1
    fi
}

# Function to update nginx configuration with new certificates
update_nginx_config() {
    log_info "Updating nginx configuration..."

    # Copy certificates to nginx SSL directory
    mkdir -p "$NGINX_SSL_DIR"

    if [[ -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]]; then
        cp "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" "$NGINX_SSL_DIR/$DOMAIN.crt"
        cp "/etc/letsencrypt/live/$DOMAIN/privkey.pem" "$NGINX_SSL_DIR/$DOMAIN.key"

        # Set proper permissions
        chmod 644 "$NGINX_SSL_DIR/$DOMAIN.crt"
        chmod 600 "$NGINX_SSL_DIR/$DOMAIN.key"

        log_info "✅ SSL certificates copied to nginx directory"
    else
        log_warn "Certificate files not found in expected location"
    fi
}

# Function to setup auto-renewal
setup_auto_renewal() {
    log_info "Setting up automatic certificate renewal..."

    # Add cron job for renewal
    (crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet --post-hook 'systemctl reload nginx'") | crontab -

    log_info "✅ Auto-renewal configured (daily check at 12:00)"
}

# Function to test nginx configuration
test_nginx_config() {
    log_info "Testing nginx configuration..."

    nginx -t
    if [[ $? -eq 0 ]]; then
        log_info "✅ Nginx configuration is valid"
        systemctl reload nginx
        log_info "✅ Nginx reloaded successfully"
    else
        log_error "❌ Nginx configuration test failed"
        exit 1
    fi
}

# Function to verify SSL certificates
verify_ssl() {
    log_info "Verifying SSL certificates..."

    # Test main domain
    if curl -s -I "https://$DOMAIN" | grep -q "200 OK"; then
        log_info "✅ $DOMAIN SSL certificate working"
    else
        log_warn "⚠️  $DOMAIN SSL certificate may have issues"
    fi

    # Test subdomains
    for subdomain in "${SUBDOMAINS[@]}"; do
        if curl -s -I "https://$subdomain.$DOMAIN" | grep -q -E "(200|404|401)"; then
            log_info "✅ $subdomain.$DOMAIN SSL certificate working"
        else
            log_warn "⚠️  $subdomain.$DOMAIN SSL certificate may have issues"
        fi
    done
}

# Function to show current certificate status
show_certificate_status() {
    log_info "Current certificate status:"

    if command -v certbot &> /dev/null; then
        certbot certificates
    else
        log_warn "Certbot not installed"
    fi

    # Check nginx SSL files
    if [[ -f "$NGINX_SSL_DIR/$DOMAIN.crt" ]]; then
        log_info "Nginx SSL certificate found: $NGINX_SSL_DIR/$DOMAIN.crt"
        openssl x509 -in "$NGINX_SSL_DIR/$DOMAIN.crt" -text -noout | grep -E "(Subject:|Not After)"
    else
        log_warn "No nginx SSL certificate found"
    fi
}

# Main menu
show_menu() {
    echo
    echo "=== Fluxer SSL Certificate Setup ==="
    echo "1. Install certbot"
    echo "2. Setup Let's Encrypt (HTTP challenge)"
    echo "3. Setup Let's Encrypt (Cloudflare DNS)"
    echo "4. Show certificate status"
    echo "5. Test nginx configuration"
    echo "6. Verify SSL certificates"
    echo "7. Exit"
    echo
}

# Main script logic
main() {
    log_info "Fluxer SSL Certificate Setup Script"
    log_info "Domain: $DOMAIN"
    log_info "Subdomains: ${SUBDOMAINS[*]}"

    if [[ $# -eq 0 ]]; then
        # Interactive mode
        while true; do
            show_menu
            read -p "Select an option (1-7): " choice

            case $choice in
                1)
                    install_certbot
                    install_cloudflare_plugin
                    ;;
                2)
                    setup_letsencrypt_http
                    test_nginx_config
                    verify_ssl
                    ;;
                3)
                    read -p "Enter Cloudflare API token: " -s cf_token
                    echo
                    setup_letsencrypt_cloudflare "$cf_token"
                    test_nginx_config
                    verify_ssl
                    ;;
                4)
                    show_certificate_status
                    ;;
                5)
                    test_nginx_config
                    ;;
                6)
                    verify_ssl
                    ;;
                7)
                    log_info "Exiting..."
                    exit 0
                    ;;
                *)
                    log_error "Invalid option. Please try again."
                    ;;
            esac

            echo
            read -p "Press Enter to continue..."
        done
    else
        # Command line mode
        case "$1" in
            "install")
                install_certbot
                install_cloudflare_plugin
                ;;
            "http")
                setup_letsencrypt_http
                test_nginx_config
                verify_ssl
                ;;
            "cloudflare")
                if [[ -z "$2" ]]; then
                    log_error "Cloudflare API token required: $0 cloudflare <api_token>"
                    exit 1
                fi
                setup_letsencrypt_cloudflare "$2"
                test_nginx_config
                verify_ssl
                ;;
            "status")
                show_certificate_status
                ;;
            "test")
                test_nginx_config
                ;;
            "verify")
                verify_ssl
                ;;
            *)
                echo "Usage: $0 [install|http|cloudflare <token>|status|test|verify]"
                echo "Run without arguments for interactive mode"
                exit 1
                ;;
        esac
    fi
}

# Run main function
main "$@"
