#!/bin/bash

# C Nostr Relay Database Initialization Script
# Creates and initializes the SQLite database with proper schema

set -e  # Exit on any error

# Configuration
DB_DIR="$(dirname "$0")"
DB_NAME="c_nostr_relay.db"
DB_PATH="${DB_DIR}/${DB_NAME}"
SCHEMA_FILE="${DB_DIR}/schema.sql"

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

# Logging functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

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

# Check if SQLite3 is installed
check_sqlite() {
    if ! command -v sqlite3 &> /dev/null; then
        log_error "sqlite3 is not installed. Please install it first:"
        echo "  Ubuntu/Debian: sudo apt-get install sqlite3"
        echo "  CentOS/RHEL:   sudo yum install sqlite"
        echo "  macOS:         brew install sqlite3"
        exit 1
    fi
    
    local version=$(sqlite3 --version | cut -d' ' -f1)
    log_info "Using SQLite version: $version"
}

# Create database directory if it doesn't exist
create_db_directory() {
    if [ ! -d "$DB_DIR" ]; then
        log_info "Creating database directory: $DB_DIR"
        mkdir -p "$DB_DIR"
    fi
}

# Backup existing database if it exists
backup_existing_db() {
    if [ -f "$DB_PATH" ]; then
        local backup_path="${DB_PATH}.backup.$(date +%Y%m%d_%H%M%S)"
        log_warning "Existing database found. Creating backup: $backup_path"
        cp "$DB_PATH" "$backup_path"
    fi
}

# Initialize the database with schema
init_database() {
    log_info "Initializing database: $DB_PATH"
    
    if [ ! -f "$SCHEMA_FILE" ]; then
        log_error "Schema file not found: $SCHEMA_FILE"
        exit 1
    fi
    
    # Remove existing database if --force flag is used
    if [ "$1" = "--force" ] && [ -f "$DB_PATH" ]; then
        log_warning "Force flag detected. Removing existing database."
        rm -f "$DB_PATH"
    fi
    
    # Create the database and apply schema
    log_info "Applying schema from: $SCHEMA_FILE"
    if sqlite3 "$DB_PATH" < "$SCHEMA_FILE"; then
        log_success "Database schema applied successfully"
    else
        log_error "Failed to apply database schema"
        exit 1
    fi
}

# Verify database integrity
verify_database() {
    log_info "Verifying database integrity..."
    
    # Check if database file exists and is not empty
    if [ ! -s "$DB_PATH" ]; then
        log_error "Database file is empty or doesn't exist"
        exit 1
    fi
    
    # Run SQLite integrity check
    local integrity_result=$(sqlite3 "$DB_PATH" "PRAGMA integrity_check;")
    if [ "$integrity_result" = "ok" ]; then
        log_success "Database integrity check passed"
    else
        log_error "Database integrity check failed: $integrity_result"
        exit 1
    fi
    
    # Verify schema version
    local schema_version=$(sqlite3 "$DB_PATH" "PRAGMA user_version;")
    log_info "Database schema version: $schema_version"
    
    # Check that main tables exist (including configuration tables)
    local table_count=$(sqlite3 "$DB_PATH" "SELECT count(*) FROM sqlite_master WHERE type='table' AND name IN ('events', 'schema_info', 'server_config');")
    if [ "$table_count" -eq 3 ]; then
        log_success "Core tables created successfully (including configuration tables)"
    else
        log_error "Missing core tables (expected 3, found $table_count)"
        exit 1
    fi
}

# Display database information
show_db_info() {
    log_info "Database Information:"
    echo "  Location: $DB_PATH"
    echo "  Size: $(du -h "$DB_PATH" | cut -f1)"
    
    log_info "Database Tables:"
    sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;" | sed 's/^/  - /'
    
    log_info "Database Indexes:"
    sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='index' AND name NOT LIKE 'sqlite_%' ORDER BY name;" | sed 's/^/  - /'
    
    log_info "Database Views:"
    sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='view' ORDER BY name;" | sed 's/^/  - /'
}

# Run database optimization
optimize_database() {
    log_info "Running database optimization..."
    sqlite3 "$DB_PATH" "PRAGMA optimize; VACUUM; ANALYZE;"
    log_success "Database optimization completed"
}

# Print usage information
print_usage() {
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Initialize SQLite database for C Nostr Relay"
    echo ""
    echo "Options:"
    echo "  --force     Remove existing database before initialization"
    echo "  --info      Show database information after initialization"
    echo "  --optimize  Run database optimization after initialization"
    echo "  --help      Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0                    # Initialize database (with backup if exists)"
    echo "  $0 --force           # Force reinitialize database"
    echo "  $0 --info --optimize # Initialize with info and optimization"
}

# Main execution
main() {
    local force_flag=false
    local show_info=false
    local optimize=false
    
    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            --force)
                force_flag=true
                shift
                ;;
            --info)
                show_info=true
                shift
                ;;
            --optimize)
                optimize=true
                shift
                ;;
            --help)
                print_usage
                exit 0
                ;;
            *)
                log_error "Unknown option: $1"
                print_usage
                exit 1
                ;;
        esac
    done
    
    log_info "Starting C Nostr Relay database initialization..."
    
    # Execute initialization steps
    check_sqlite
    create_db_directory
    
    if [ "$force_flag" = false ]; then
        backup_existing_db
    fi
    
    if [ "$force_flag" = true ]; then
        init_database --force
    else
        init_database
    fi
    
    verify_database
    
    if [ "$optimize" = true ]; then
        optimize_database
    fi
    
    if [ "$show_info" = true ]; then
        show_db_info
    fi
    
    log_success "Database initialization completed successfully!"
    echo ""
    echo "Database ready at: $DB_PATH"
    echo "You can now start your C Nostr Relay application."
}

# Execute main function with all arguments
main "$@"