#!/usr/bin/env python3
"""
Python entrypoint script for TimeTracker Docker container
This avoids shell script line ending issues and provides better error handling
"""

import os
import sys
import time
import subprocess
import traceback
import psycopg2
from urllib.parse import urlparse

def log(message):
    """Log message with timestamp"""
    from datetime import datetime
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print(f"[{timestamp}] {message}")

def wait_for_database():
    """Wait for database to be ready"""
    log("Waiting for database to be available...")
    
    db_url = os.getenv('DATABASE_URL')
    if not db_url:
        log("✗ DATABASE_URL environment variable not set")
        return False
    
    log(f"Database URL: {db_url}")
    
    max_attempts = 30
    retry_delay = 2
    
    for attempt in range(1, max_attempts + 1):
        log(f"Attempt {attempt}/{max_attempts} to connect to database...")
        
        try:
            if db_url.startswith('postgresql'):
                # Parse connection string
                if db_url.startswith('postgresql+psycopg2://'):
                    db_url = db_url.replace('postgresql+psycopg2://', '')
                
                if '@' in db_url:
                    auth_part, rest = db_url.split('@', 1)
                    user, password = auth_part.split(':', 1)
                    if ':' in rest:
                        host_port, database = rest.rsplit('/', 1)
                        if ':' in host_port:
                            host, port = host_port.split(':', 1)
                        else:
                            host, port = host_port, '5432'
                    else:
                        host, port, database = rest, '5432', 'timetracker'
                else:
                    host, port, database, user, password = 'db', '5432', 'timetracker', 'timetracker', 'timetracker'
                
                conn = psycopg2.connect(
                    host=host,
                    port=port,
                    database=database,
                    user=user,
                    password=password,
                    connect_timeout=5
                )
                conn.close()
                log("✓ PostgreSQL database is available")
                return True
                
            elif db_url.startswith('sqlite://'):
                db_file = db_url.replace('sqlite://', '')
                if os.path.exists(db_file) or os.access(os.path.dirname(db_file), os.W_OK):
                    log("✓ SQLite database is available")
                    return True
                else:
                    log("SQLite file not accessible")
            else:
                log(f"Unknown database URL format: {db_url}")
                
        except Exception as e:
            log(f"Database connection failed: {e}")
        
        if attempt < max_attempts:
            log(f"Waiting {retry_delay} seconds before next attempt...")
            time.sleep(retry_delay)
    
    log("✗ Database is not available after maximum retries")
    return False

def run_migrations():
    """Run database migrations"""
    log("Checking migrations...")
    
    try:
        # Check if migrations directory exists
        if os.path.exists("/app/migrations"):
            log("Migrations directory exists, checking status...")
            
            # Try to apply any pending migrations
            result = subprocess.run(['flask', 'db', 'upgrade'], 
                                  capture_output=True, text=True, timeout=60)
            if result.returncode == 0:
                log("✓ Migrations applied successfully")
                return True
            else:
                log(f"⚠ Migration application failed: {result.stderr}")
                return False
        else:
            log("No migrations directory found, initializing...")
            
            # Initialize migrations
            result = subprocess.run(['flask', 'db', 'init'], 
                                  capture_output=True, text=True, timeout=60)
            if result.returncode == 0:
                log("✓ Migrations initialized")
                
                # Create initial migration
                result = subprocess.run(['flask', 'db', 'migrate', '-m', 'Initial schema'], 
                                      capture_output=True, text=True, timeout=60)
                if result.returncode == 0:
                    log("✓ Initial migration created")
                    
                    # Apply migration
                    result = subprocess.run(['flask', 'db', 'upgrade'], 
                                          capture_output=True, text=True, timeout=60)
                    if result.returncode == 0:
                        log("✓ Initial migration applied")
                        return True
                    else:
                        log(f"⚠ Initial migration application failed: {result.stderr}")
                        return False
                else:
                    log(f"⚠ Initial migration creation failed: {result.stderr}")
                    return False
            else:
                log(f"⚠ Migration initialization failed: {result.stderr}")
                return False
                
    except subprocess.TimeoutExpired:
        log("⚠ Migration operation timed out")
        return False
    except Exception as e:
        log(f"⚠ Migration error: {e}")
        return False

def main():
    """Main entrypoint function"""
    log("=== TimeTracker Docker Entrypoint ===")
    
    # Set environment variables
    os.environ.setdefault('FLASK_APP', '/app/app.py')
    
    # Wait for database
    if not wait_for_database():
        log("✗ Failed to connect to database")
        sys.exit(1)
    
    # Run migrations
    if not run_migrations():
        log("⚠ Migration issues detected, continuing anyway")
    
    log("=== Startup Complete ===")
    log("Starting TimeTracker application...")
    
    # Execute the command passed to the container
    if len(sys.argv) > 1:
        try:
            os.execv(sys.argv[1], sys.argv[1:])
        except Exception as e:
            log(f"✗ Failed to execute command: {e}")
            sys.exit(1)
    else:
        # Default command
        try:
            os.execv('/usr/bin/python', ['python', '/app/start.py'])
        except Exception as e:
            log(f"✗ Failed to execute default command: {e}")
            sys.exit(1)

if __name__ == "__main__":
    main()
