#!/usr/bin/env python3
"""
New Idempotent Database Setup for PinePods

This script replaces the old setupdatabase.py and setuppostgresdatabase.py
with a proper migration-based system that is fully idempotent.
"""

import os
import sys
import logging
from pathlib import Path

# Set up basic configuration for logging
logging.basicConfig(
    level=logging.INFO, 
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Add pinepods directory to sys.path for module import
pinepods_path = Path(__file__).parent.parent
sys.path.insert(0, str(pinepods_path))
sys.path.insert(0, '/pinepods')  # Also add the container path for Docker

def wait_for_postgresql_ready():
    """Wait for PostgreSQL to be ready to accept connections (not just port open)"""
    import time
    import psycopg
    
    db_host = os.environ.get("DB_HOST", "127.0.0.1")
    db_port = os.environ.get("DB_PORT", "5432")
    db_user = os.environ.get("DB_USER", "postgres")
    db_password = os.environ.get("DB_PASSWORD", "password")
    
    max_attempts = 30  # 30 seconds
    attempt = 1
    
    logger.info(f"Waiting for PostgreSQL at {db_host}:{db_port} to be ready...")
    
    while attempt <= max_attempts:
        try:
            # Try to connect to the postgres database
            with psycopg.connect(
                host=db_host,
                port=db_port,
                user=db_user,
                password=db_password,
                dbname='postgres',
                connect_timeout=3
            ) as conn:
                with conn.cursor() as cur:
                    # Test if PostgreSQL is ready to accept queries
                    cur.execute("SELECT 1")
                    cur.fetchone()
                logger.info(f"PostgreSQL is ready after {attempt} attempts")
                return True
        except Exception as e:
            if "not yet accepting connections" in str(e) or "recovery" in str(e).lower():
                logger.info(f"PostgreSQL not ready yet (attempt {attempt}/{max_attempts}): {e}")
            else:
                logger.warning(f"Connection attempt {attempt}/{max_attempts} failed: {e}")
            
            if attempt < max_attempts:
                time.sleep(1)
            attempt += 1
    
    logger.error(f"PostgreSQL failed to become ready after {max_attempts} attempts")
    return False

def wait_for_mysql_ready():
    """Wait for MySQL/MariaDB to be ready to accept connections"""
    import time
    try:
        import mariadb as mysql_connector
    except ImportError:
        import mysql.connector
    
    db_host = os.environ.get("DB_HOST", "127.0.0.1")
    db_port = int(os.environ.get("DB_PORT", "3306"))
    db_user = os.environ.get("DB_USER", "root")
    db_password = os.environ.get("DB_PASSWORD", "password")
    
    max_attempts = 30  # 30 seconds
    attempt = 1
    
    logger.info(f"Waiting for MySQL/MariaDB at {db_host}:{db_port} to be ready...")
    
    while attempt <= max_attempts:
        try:
            # Try to connect to MySQL/MariaDB
            conn = mysql_connector.connect(
                host=db_host,
                port=db_port,
                user=db_user,
                password=db_password,
                connect_timeout=3,
                autocommit=True
            )
            cursor = conn.cursor()
            # Test if MySQL is ready to accept queries
            cursor.execute("SELECT 1")
            cursor.fetchone()
            cursor.close()
            conn.close()
            logger.info(f"MySQL/MariaDB is ready after {attempt} attempts")
            return True
        except Exception as e:
            logger.info(f"MySQL/MariaDB not ready yet (attempt {attempt}/{max_attempts}): {e}")
            
            if attempt < max_attempts:
                time.sleep(1)
            attempt += 1
    
    logger.error(f"MySQL/MariaDB failed to become ready after {max_attempts} attempts")
    return False

def create_database_if_not_exists():
    """Create the database if it doesn't exist and wait for database to be ready"""
    db_type = os.environ.get("DB_TYPE", "postgresql").lower()
    
    if db_type in ['postgresql', 'postgres']:
        # First, wait for PostgreSQL to be ready
        if not wait_for_postgresql_ready():
            raise Exception("PostgreSQL did not become ready in time")
    else:
        # Wait for MySQL/MariaDB to be ready
        if not wait_for_mysql_ready():
            raise Exception("MySQL/MariaDB did not become ready in time")
        logger.info("MySQL/MariaDB is ready (database creation handled by container)")
        return
    
    # PostgreSQL database creation logic continues below
    if not wait_for_postgresql_ready():
        raise Exception("PostgreSQL did not become ready in time")
    
    try:
        import psycopg
        
        # Database connection parameters
        db_host = os.environ.get("DB_HOST", "127.0.0.1")
        db_port = os.environ.get("DB_PORT", "5432")
        db_user = os.environ.get("DB_USER", "postgres")
        db_password = os.environ.get("DB_PASSWORD", "password")
        db_name = os.environ.get("DB_NAME", "pinepods_database")
        
        # Connect to the default 'postgres' database to check/create target database
        with psycopg.connect(
            host=db_host,
            port=db_port,
            user=db_user,
            password=db_password,
            dbname='postgres'
        ) as conn:
            conn.autocommit = True
            with conn.cursor() as cur:
                # Check if the database exists
                cur.execute("SELECT 1 FROM pg_database WHERE datname = %s", (db_name,))
                exists = cur.fetchone()
                if not exists:
                    logger.info(f"Database {db_name} does not exist. Creating...")
                    cur.execute(f"CREATE DATABASE {db_name}")
                    logger.info(f"Database {db_name} created successfully.")
                else:
                    logger.info(f"Database {db_name} already exists.")
                    
    except ImportError:
        logger.error("psycopg not available for PostgreSQL database creation")
        raise
    except Exception as e:
        logger.error(f"Error creating database: {e}")
        raise


def ensure_usernames_lowercase():
    """Ensure all usernames are lowercase for consistency"""
    try:
        from database_functions.migrations import get_migration_manager
        
        manager = get_migration_manager()
        conn = manager.get_connection()
        cursor = conn.cursor()
        
        db_type = manager.db_type
        table_name = '"Users"' if db_type == 'postgresql' else 'Users'
        
        try:
            cursor.execute(f'SELECT UserID, Username FROM {table_name}')
            users = cursor.fetchall()
            
            for user_id, username in users:
                if username and username != username.lower():
                    cursor.execute(
                        f'UPDATE {table_name} SET Username = %s WHERE UserID = %s', 
                        (username.lower(), user_id)
                    )
                    logger.info(f"Updated Username for UserID {user_id} to lowercase")
            
            conn.commit()
            logger.info("Username normalization completed")
            
        finally:
            cursor.close()
            manager.close_connection()
            
    except Exception as e:
        logger.error(f"Error normalizing usernames: {e}")


def ensure_web_api_key_file():
    """Deprecated: Web API key file removed for security reasons"""
    logger.info("Web API key file creation skipped - background tasks now authenticate via database")


def main():
    """Main setup function"""
    try:
        logger.info("Starting PinePods database setup...")
        
        # Step 1: Create database if needed (PostgreSQL only)
        create_database_if_not_exists()
        
        # Step 2: Import and register all migrations
        logger.info("Loading migration definitions...")
        import database_functions.migration_definitions
        database_functions.migration_definitions.register_all_migrations()
        
        # Step 3: Run migrations
        logger.info("Running database migrations...")
        from database_functions.migrations import run_all_migrations
        
        success = run_all_migrations()
        if not success:
            logger.error("Database migrations failed!")
            return False
        
        # Step 4: Ensure username consistency
        logger.info("Ensuring username consistency...")
        ensure_usernames_lowercase()
        
        # Step 5: Ensure web API key file exists
        logger.info("Ensuring web API key file exists...")
        ensure_web_api_key_file()
        
        logger.info("Database setup completed successfully!")
        logger.info("Database validation complete")
        
        return True
        
    except Exception as e:
        logger.error(f"Database setup failed: {e}")
        return False


if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)