#!/bin/bash

# Fluxer Cloudflare SSL Certificate Setup Script
# This script helps set up SSL certificates for Fluxer using Cloudflare Origin Certificates

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'
BLUE='\033[0;34m'
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"
}

log_note() {
    echo -e "${BLUE}[NOTE]${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 check current certificate status
check_current_certificate() {
    log_info "Checking current SSL certificate for $DOMAIN..."

    if [[ -f "$NGINX_SSL_DIR/$DOMAIN.crt" ]]; then
        log_info "Current certificate found: $NGINX_SSL_DIR/$DOMAIN.crt"

        # Check certificate details
        echo "Certificate details:"
        openssl x509 -in "$NGINX_SSL_DIR/$DOMAIN.crt" -text -noout | grep -E "(Subject:|Not After|DNS:)"

        # Check if it's a wildcard or includes subdomains
        if openssl x509 -in "$NGINX_SSL_DIR/$DOMAIN.crt" -text -noout | grep -q "DNS:\*\.$DOMAIN"; then
            log_info "✅ Wildcard certificate detected - should cover all subdomains"
            return 0
        elif openssl x509 -in "$NGINX_SSL_DIR/$DOMAIN.crt" -text -noout | grep -q "DNS:api\.$DOMAIN"; then
            log_info "✅ Multi-domain certificate detected - checking coverage..."
            for subdomain in "${SUBDOMAINS[@]}"; do
                if openssl x509 -in "$NGINX_SSL_DIR/$DOMAIN.crt" -text -noout | grep -q "DNS:$subdomain\.$DOMAIN"; then
                    log_info "  ✅ $subdomain.$DOMAIN covered"
                else
                    log_warn "  ❌ $subdomain.$DOMAIN NOT covered"
                fi
            done
        else
            log_warn "⚠️  Certificate only covers $DOMAIN - subdomains need separate certificate"
            return 1
        fi
    else
        log_error "No SSL certificate found for $DOMAIN"
        return 1
    fi
}

# Function to show Cloudflare Origin Certificate instructions
show_cloudflare_instructions() {
    log_info "Cloudflare Origin Certificate Setup Instructions"
    echo
    echo "To create a new Cloudflare Origin Certificate that covers all Fluxer subdomains:"
    echo
    echo "1. Go to Cloudflare Dashboard → SSL/TLS → Origin Server"
    echo "2. Click 'Create Certificate'"
    echo "3. Choose 'Let Cloudflare generate a private key and a CSR'"
    echo "4. Set hostnames to:"
    echo "   - $DOMAIN"
    echo "   - *.$DOMAIN"
    echo "   OR specify each subdomain individually:"
    for subdomain in "${SUBDOMAINS[@]}"; do
        echo "   - $subdomain.$DOMAIN"
    done
    echo "5. Choose certificate validity (15 years recommended)"
    echo "6. Click 'Create'"
    echo "7. Copy the certificate and private key"
    echo
    log_note "The wildcard option (*.st.vish.gg) is recommended as it covers all current and future subdomains"
}

# Function to install new certificate
install_certificate() {
    local cert_file="$1"
    local key_file="$2"

    if [[ ! -f "$cert_file" ]] || [[ ! -f "$key_file" ]]; then
        log_error "Certificate or key file not found"
        return 1
    fi

    log_info "Installing new certificate..."

    # Backup existing certificate
    if [[ -f "$NGINX_SSL_DIR/$DOMAIN.crt" ]]; then
        cp "$NGINX_SSL_DIR/$DOMAIN.crt" "$NGINX_SSL_DIR/$DOMAIN.crt.backup.$(date +%Y%m%d_%H%M%S)"
        cp "$NGINX_SSL_DIR/$DOMAIN.key" "$NGINX_SSL_DIR/$DOMAIN.key.backup.$(date +%Y%m%d_%H%M%S)"
        log_info "Existing certificate backed up"
    fi

    # Install new certificate
    cp "$cert_file" "$NGINX_SSL_DIR/$DOMAIN.crt"
    cp "$key_file" "$NGINX_SSL_DIR/$DOMAIN.key"

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

    log_info "✅ New certificate installed"

    # Verify certificate
    if openssl x509 -in "$NGINX_SSL_DIR/$DOMAIN.crt" -text -noout > /dev/null 2>&1; then
        log_info "✅ Certificate validation successful"
    else
        log_error "❌ Certificate validation failed"
        return 1
    fi
}

# Function to update nginx configuration for subdomains
update_nginx_subdomain_config() {
    log_info "Updating nginx configuration for Fluxer subdomains..."

    # Check if Fluxer nginx config exists
    if [[ ! -f "$NGINX_SITES_DIR/fluxer" ]]; then
        log_error "Fluxer nginx configuration not found at $NGINX_SITES_DIR/fluxer"
        return 1
    fi

    log_info "✅ Fluxer nginx configuration found"

    # Test 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"
        return 1
    fi
}

# Function to test SSL connectivity
test_ssl_connectivity() {
    log_info "Testing SSL connectivity for all domains..."

    # Test main domain
    log_info "Testing $DOMAIN..."
    if curl -s -I --max-time 10 "https://$DOMAIN" | grep -q -E "(200|404)"; then
        log_info "✅ $DOMAIN SSL working"
    else
        log_warn "⚠️  $DOMAIN SSL may have issues"
    fi

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

# Function to show DNS requirements
show_dns_requirements() {
    log_info "DNS Requirements for Fluxer Subdomains"
    echo
    echo "Ensure the following DNS records exist in Cloudflare:"
    echo
    echo "Type  | Name                | Target        | Proxy Status"
    echo "------|---------------------|---------------|-------------"
    echo "A     | $DOMAIN             | YOUR_SERVER_IP| Grey Cloud"
    echo "CNAME | api.$DOMAIN         | $DOMAIN       | Grey Cloud"
    echo "CNAME | events.$DOMAIN      | $DOMAIN       | Grey Cloud"
    echo "CNAME | files.$DOMAIN       | $DOMAIN       | Grey Cloud"
    echo "CNAME | voice.$DOMAIN       | $DOMAIN       | Grey Cloud"
    echo "CNAME | proxy.$DOMAIN       | $DOMAIN       | Grey Cloud"
    echo
    log_note "Grey Cloud (DNS-only) is required for origin certificates to work properly"
}

# Function to show certificate generation guide
show_certificate_guide() {
    echo
    echo "=== Cloudflare Origin Certificate Generation Guide ==="
    echo
    echo "Step 1: Access Cloudflare Dashboard"
    echo "  - Go to https://dash.cloudflare.com"
    echo "  - Select your domain: $DOMAIN"
    echo
    echo "Step 2: Navigate to SSL/TLS Settings"
    echo "  - Click on 'SSL/TLS' in the left sidebar"
    echo "  - Click on 'Origin Server' tab"
    echo
    echo "Step 3: Create Origin Certificate"
    echo "  - Click 'Create Certificate' button"
    echo "  - Select 'Let Cloudflare generate a private key and a CSR'"
    echo
    echo "Step 4: Configure Certificate"
    echo "  - Hostnames: Enter the following (one per line):"
    echo "    $DOMAIN"
    echo "    *.$DOMAIN"
    echo "  - Certificate Validity: 15 years (recommended)"
    echo "  - Click 'Create'"
    echo
    echo "Step 5: Save Certificate Files"
    echo "  - Copy the 'Origin Certificate' content to a file (e.g., /tmp/st.vish.gg.crt)"
    echo "  - Copy the 'Private Key' content to a file (e.g., /tmp/st.vish.gg.key)"
    echo
    echo "Step 6: Install Certificate"
    echo "  - Run: $0 install /tmp/st.vish.gg.crt /tmp/st.vish.gg.key"
    echo
    log_note "The wildcard certificate (*.st.vish.gg) will cover all current and future subdomains"
}

# Main menu
show_menu() {
    echo
    echo "=== Fluxer Cloudflare SSL Certificate Setup ==="
    echo "1. Check current certificate status"
    echo "2. Show certificate generation guide"
    echo "3. Install new certificate (provide cert and key files)"
    echo "4. Update nginx configuration"
    echo "5. Test SSL connectivity"
    echo "6. Show DNS requirements"
    echo "7. Show Cloudflare instructions"
    echo "8. Exit"
    echo
}

# Main script logic
main() {
    log_info "Fluxer Cloudflare SSL Certificate Setup"
    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-8): " choice

            case $choice in
                1)
                    check_current_certificate
                    ;;
                2)
                    show_certificate_guide
                    ;;
                3)
                    read -p "Enter path to certificate file: " cert_file
                    read -p "Enter path to private key file: " key_file
                    install_certificate "$cert_file" "$key_file"
                    ;;
                4)
                    update_nginx_subdomain_config
                    ;;
                5)
                    test_ssl_connectivity
                    ;;
                6)
                    show_dns_requirements
                    ;;
                7)
                    show_cloudflare_instructions
                    ;;
                8)
                    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
            "check")
                check_current_certificate
                ;;
            "install")
                if [[ -z "$2" ]] || [[ -z "$3" ]]; then
                    log_error "Usage: $0 install <cert_file> <key_file>"
                    exit 1
                fi
                install_certificate "$2" "$3"
                update_nginx_subdomain_config
                ;;
            "test")
                test_ssl_connectivity
                ;;
            "dns")
                show_dns_requirements
                ;;
            "guide")
                show_certificate_guide
                ;;
            *)
                echo "Usage: $0 [check|install <cert> <key>|test|dns|guide]"
                echo "Run without arguments for interactive mode"
                exit 1
                ;;
        esac
    fi
}

# Run main function
main "$@"
