#!/bin/bash

# Rustelo Feature Configuration Helper
# This script helps configure optional features for the Rustelo template

set -e

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

# Default values
ENABLE_TLS=false
ENABLE_AUTH=true
ENABLE_CONTENT_DB=true
INTERACTIVE=true
BUILD_TYPE="debug"
OUTPUT_FILE=".env"

# Function to print colored output
print_color() {
    printf "${1}${2}${NC}\n"
}

# Function to show usage
show_usage() {
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  -h, --help                Show this help message"
    echo "  -i, --interactive         Interactive mode (default)"
    echo "  -n, --non-interactive     Non-interactive mode"
    echo "  -t, --tls                 Enable TLS support"
    echo "  -a, --auth                Enable authentication (default)"
    echo "  -c, --content-db          Enable database content (default)"
    echo "  --no-auth                 Disable authentication"
    echo "  --no-content-db           Disable database content"
    echo "  --minimal                 Minimal setup (no optional features)"
    echo "  --build-release           Build in release mode"
    echo "  --build-debug             Build in debug mode (default)"
    echo "  -o, --output FILE         Output environment file (default: .env)"
    echo "  --dry-run                 Show configuration without applying"
    echo ""
    echo "Examples:"
    echo "  $0                        Interactive configuration"
    echo "  $0 --minimal              Minimal setup"
    echo "  $0 --tls --auth           Enable TLS and auth only"
    echo "  $0 --non-interactive      Use defaults non-interactively"
}

# Function to ask yes/no question
ask_yes_no() {
    local question="$1"
    local default="$2"
    local response

    if [ "$INTERACTIVE" = false ]; then
        return $default
    fi

    while true; do
        if [ "$default" = "0" ]; then
            printf "${BLUE}${question} [Y/n]: ${NC}"
        else
            printf "${BLUE}${question} [y/N]: ${NC}"
        fi

        read -r response
        case "$response" in
            [Yy]|[Yy][Ee][Ss]) return 0 ;;
            [Nn]|[Nn][Oo]) return 1 ;;
            "") return $default ;;
            *) echo "Please answer yes or no." ;;
        esac
    done
}

# Function to get input with default
get_input() {
    local prompt="$1"
    local default="$2"
    local response

    if [ "$INTERACTIVE" = false ]; then
        echo "$default"
        return
    fi

    printf "${BLUE}${prompt} [${default}]: ${NC}"
    read -r response

    if [ -z "$response" ]; then
        echo "$default"
    else
        echo "$response"
    fi
}

# Function to generate .env file
generate_env_file() {
    local file="$1"

    print_color "$GREEN" "Generating environment configuration in $file..."

    cat > "$file" << EOF
# Rustelo Configuration
# Generated by configure-features.sh on $(date)

# Server Configuration
SERVER_HOST=127.0.0.1
SERVER_PORT=3030
SERVER_PROTOCOL=$(if [ "$ENABLE_TLS" = true ]; then echo "https"; else echo "http"; fi)
ENVIRONMENT=DEV
LOG_LEVEL=info

EOF

    if [ "$ENABLE_TLS" = true ]; then
        cat >> "$file" << EOF
# TLS Configuration
TLS_CERT_PATH=./certs/cert.pem
TLS_KEY_PATH=./certs/key.pem

EOF
    fi

    if [ "$ENABLE_AUTH" = true ] || [ "$ENABLE_CONTENT_DB" = true ]; then
        cat >> "$file" << EOF
# Database Configuration
DATABASE_URL=postgres://username:password@localhost:5432/rustelo_dev

EOF
    fi

    if [ "$ENABLE_AUTH" = true ]; then
        cat >> "$file" << EOF
# Authentication Configuration
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_EXPIRATION_HOURS=24

# OAuth Providers (optional)
# GOOGLE_CLIENT_ID=your-google-client-id
# GOOGLE_CLIENT_SECRET=your-google-client-secret
# GITHUB_CLIENT_ID=your-github-client-id
# GITHUB_CLIENT_SECRET=your-github-client-secret

# 2FA Configuration
TOTP_ISSUER=Rustelo
TOTP_SERVICE_NAME=Rustelo Authentication

EOF
    fi

    if [ "$ENABLE_CONTENT_DB" = true ]; then
        cat >> "$file" << EOF
# Content Management Configuration
CONTENT_CACHE_ENABLED=true
CONTENT_CACHE_TTL=3600

EOF
    fi
}

# Function to generate build command
get_build_command() {
    local features=""
    local feature_list=()

    if [ "$ENABLE_TLS" = true ]; then
        feature_list+=("tls")
    fi

    if [ "$ENABLE_AUTH" = true ]; then
        feature_list+=("auth")
    fi

    if [ "$ENABLE_CONTENT_DB" = true ]; then
        feature_list+=("content-db")
    fi

    if [ ${#feature_list[@]} -eq 0 ]; then
        features="--no-default-features"
    else
        features="--features $(IFS=,; echo "${feature_list[*]}")"
    fi

    local build_cmd="cargo build"
    if [ "$BUILD_TYPE" = "release" ]; then
        build_cmd="cargo build --release"
    fi

    echo "$build_cmd $features"
}

# Function to show configuration summary
show_summary() {
    print_color "$BLUE" "Configuration Summary:"
    echo "========================"
    echo "TLS Support:        $(if [ "$ENABLE_TLS" = true ]; then echo "✓ Enabled"; else echo "✗ Disabled"; fi)"
    echo "Authentication:     $(if [ "$ENABLE_AUTH" = true ]; then echo "✓ Enabled"; else echo "✗ Disabled"; fi)"
    echo "Database Content:   $(if [ "$ENABLE_CONTENT_DB" = true ]; then echo "✓ Enabled"; else echo "✗ Disabled"; fi)"
    echo "Build Type:         $BUILD_TYPE"
    echo "Output File:        $OUTPUT_FILE"
    echo ""
    echo "Build Command:      $(get_build_command)"
    echo "========================"
}

# Function to interactive configuration
interactive_config() {
    print_color "$GREEN" "Rustelo Feature Configuration"
    print_color "$BLUE" "================================"

    echo "This script will help you configure optional features for your Rustelo application."
    echo ""

    # TLS Configuration
    if ask_yes_no "Enable TLS/HTTPS support?" 1; then
        ENABLE_TLS=true
        print_color "$YELLOW" "Note: You'll need to provide TLS certificates for HTTPS."
    fi

    # Authentication Configuration
    if ask_yes_no "Enable authentication system (JWT, OAuth, 2FA)?" 0; then
        ENABLE_AUTH=true
        print_color "$YELLOW" "Note: Authentication requires database connection."
    else
        ENABLE_AUTH=false
    fi

    # Content Database Configuration
    if ask_yes_no "Enable database-driven content management?" 0; then
        ENABLE_CONTENT_DB=true
        print_color "$YELLOW" "Note: Database content requires database connection."
    else
        ENABLE_CONTENT_DB=false
    fi

    # Build type
    if ask_yes_no "Build in release mode?" 1; then
        BUILD_TYPE="release"
    else
        BUILD_TYPE="debug"
    fi

    # Output file
    OUTPUT_FILE=$(get_input "Environment file location" ".env")
}

# Function to validate configuration
validate_config() {
    local errors=()

    # Check if we need database but don't have any features that require it
    if [ "$ENABLE_AUTH" = false ] && [ "$ENABLE_CONTENT_DB" = false ]; then
        print_color "$YELLOW" "Warning: No database features enabled. Database won't be used."
    fi

    # Check for TLS requirements
    if [ "$ENABLE_TLS" = true ]; then
        if [ ! -d "certs" ]; then
            print_color "$YELLOW" "Warning: TLS enabled but 'certs' directory not found."
            print_color "$YELLOW" "You'll need to create certificates before running with HTTPS."
        fi
    fi

    if [ ${#errors[@]} -gt 0 ]; then
        print_color "$RED" "Configuration errors:"
        for error in "${errors[@]}"; do
            echo "  - $error"
        done
        return 1
    fi

    return 0
}

# Function to create sample certificates
create_sample_certs() {
    if [ "$ENABLE_TLS" = true ] && [ ! -d "certs" ]; then
        if ask_yes_no "Create sample self-signed certificates for development?" 0; then
            print_color "$BLUE" "Creating sample certificates..."
            mkdir -p certs

            # Generate self-signed certificate
            openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem \
                -days 365 -nodes -subj "/CN=localhost" 2>/dev/null

            if [ $? -eq 0 ]; then
                print_color "$GREEN" "Sample certificates created in certs/ directory."
                print_color "$YELLOW" "Warning: These are self-signed certificates for development only!"
            else
                print_color "$RED" "Failed to create certificates. Please install OpenSSL."
            fi
        fi
    fi
}

# Main function
main() {
    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_usage
                exit 0
                ;;
            -i|--interactive)
                INTERACTIVE=true
                shift
                ;;
            -n|--non-interactive)
                INTERACTIVE=false
                shift
                ;;
            -t|--tls)
                ENABLE_TLS=true
                shift
                ;;
            -a|--auth)
                ENABLE_AUTH=true
                shift
                ;;
            -c|--content-db)
                ENABLE_CONTENT_DB=true
                shift
                ;;
            --no-auth)
                ENABLE_AUTH=false
                shift
                ;;
            --no-content-db)
                ENABLE_CONTENT_DB=false
                shift
                ;;
            --minimal)
                ENABLE_TLS=false
                ENABLE_AUTH=false
                ENABLE_CONTENT_DB=false
                shift
                ;;
            --build-release)
                BUILD_TYPE="release"
                shift
                ;;
            --build-debug)
                BUILD_TYPE="debug"
                shift
                ;;
            -o|--output)
                OUTPUT_FILE="$2"
                shift 2
                ;;
            --dry-run)
                DRY_RUN=true
                shift
                ;;
            *)
                print_color "$RED" "Unknown option: $1"
                show_usage
                exit 1
                ;;
        esac
    done

    # Run interactive configuration if enabled
    if [ "$INTERACTIVE" = true ]; then
        interactive_config
    fi

    # Validate configuration
    if ! validate_config; then
        exit 1
    fi

    # Show summary
    show_summary

    # Generate configuration if not dry run
    if [ "$DRY_RUN" != true ]; then
        if [ "$INTERACTIVE" = true ]; then
            if ! ask_yes_no "Apply this configuration?" 0; then
                print_color "$YELLOW" "Configuration cancelled."
                exit 0
            fi
        fi

        generate_env_file "$OUTPUT_FILE"
        create_sample_certs

        print_color "$GREEN" "Configuration complete!"
        print_color "$BLUE" "Next steps:"
        echo "1. Review the generated $OUTPUT_FILE file"
        echo "2. Update database connection if needed"
        echo "3. Configure OAuth providers if using authentication"
        echo "4. Run: $(get_build_command)"
        echo "5. Start the server: cargo run"
    else
        print_color "$BLUE" "Dry run mode - no files were modified."
    fi
}

# Run main function
main "$@"
