#!/usr/bin/env python
"""
Test script to debug subprocess spawning from the API.
"""

import os
import sys
import django
from django.conf import settings

# Setup Django environment
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'iching.settings')
django.setup()

from django.contrib.auth import get_user_model
from django.test import RequestFactory
from api.views_person_relations import PersonRelationsAPIView

def test_subprocess_spawning():
    """Test the subprocess spawning functionality"""
    print("=== Testing Subprocess Spawning Debug ===")
    
    # Get user
    User = get_user_model()
    user = User.objects.get(id=1)
    print(f"Testing with user: {user.id} ({user.email or user.username})")
    print(f"Current state: {user.group_relations_state}")
    
    # Create a mock request
    factory = RequestFactory()
    request = factory.get('/api/bazi/person-relations/')
    request.user = user
    
    # Call the API view
    print("\n--- Calling API View ---")
    view = PersonRelationsAPIView()
    response = view.get(request)
    
    print(f"Response status: {response.status_code}")
    print(f"Response data: {response.data}")
    
    # Check if state changed
    user.refresh_from_db()
    print(f"User state after API call: {user.group_relations_state}")
    
    # Wait a moment for subprocess to start
    import time
    print("\n--- Waiting for subprocess to start ---")
    time.sleep(2)
    
    # Check if subprocess is running
    import subprocess
    try:
        result = subprocess.run(['ps', 'aux'], capture_output=True, text=True)
        if 'recalc_bazi_relations' in result.stdout:
            print("✓ Background process found running:")
            for line in result.stdout.split('\n'):
                if 'recalc_bazi_relations' in line:
                    print(f"  {line.strip()}")
        else:
            print("✗ No background process found")
    except Exception as e:
        print(f"Error checking processes: {e}")
    
    print("\n=== Test Complete ===")
    print("Check Django logs for subprocess spawning details.")

def test_direct_subprocess():
    """Test subprocess spawning directly to debug the issue"""
    print("\n=== Testing Direct Subprocess Spawning ===")
    
    import subprocess
    import os
    
    # Test the path calculation
    current_file = __file__
    print(f"Current file: {current_file}")
    
    # Calculate working directory - go up one level from test file to project root
    cwd = os.path.dirname(current_file)
    print(f"Calculated cwd: {cwd}")
    
    # Check if manage.py exists
    manage_path = os.path.join(cwd, "manage.py")
    print(f"manage.py path: {manage_path}")
    print(f"manage.py exists: {os.path.exists(manage_path)}")
    
    # List files in the directory
    if os.path.exists(cwd):
        print(f"Files in {cwd}: {os.listdir(cwd)[:10]}")
    
    # Try to spawn the subprocess directly
    print("\n--- Testing Subprocess Spawn ---")
    try:
        env = os.environ.copy()
        env["DJANGO_ENV"] = "development"
        
        print(f"Environment: DJANGO_ENV={env.get('DJANGO_ENV')}")
        print(f"Python executable: {sys.executable}")
        
        # Use shell script approach to completely isolate from uWSGI
        import tempfile
        
        # Create a temporary shell script that will execute the management command
        script_content = f'''#!/bin/bash
cd "{cwd}"

# Activate the virtual environment
source venv/bin/activate

# Set environment variables
export DJANGO_ENV="{env.get('DJANGO_ENV', 'development')}"
export PYTHONPATH="{cwd}"
export DJANGO_SETTINGS_MODULE="iching.settings"

# Execute the management command and log the result
python manage.py recalc_bazi_relations --user 1 --force > logs/recalc_bazi_relations_wrapper.log 2>&1

# Log completion status
echo "Command completed at $(date)" >> logs/recalc_bazi_relations_wrapper.log
'''
        
        # Write the wrapper script to a temporary file
        with tempfile.NamedTemporaryFile(mode='w', suffix='.sh', delete=False) as f:
            f.write(script_content)
            script_path = f.name
        
        # Make the script executable
        os.chmod(script_path, 0o755)
        
        # Execute the wrapper script in background using bash
        process = subprocess.Popen([
            '/bin/bash', script_path
        ], env=env, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True)
        
        # Clean up the temporary script after a delay
        def cleanup_script():
            import time
            time.sleep(5)  # Wait for script to start
            try:
                os.unlink(script_path)
            except:
                pass
        
        import threading
        cleanup_thread = threading.Thread(target=cleanup_script, daemon=True)
        cleanup_thread.start()
        
        print(f"Process spawned with PID: {process.pid}")
        
        # Wait a moment and check status
        import time
        time.sleep(1)
        
        if process.poll() is None:
            print("✓ Process is running")
            process.terminate()
            process.wait()
            print("Process terminated")
        else:
            print(f"✗ Process exited with code: {process.returncode}")
            stdout, stderr = process.communicate()
            if stderr:
                print(f"stderr: {stderr.decode('utf-8', errors='ignore')}")
            if stdout:
                print(f"stdout: {stdout.decode('utf-8', errors='ignore')}")
                
    except Exception as e:
        print(f"Error spawning subprocess: {e}")
        import traceback
        traceback.print_exc()

if __name__ == '__main__':
    test_subprocess_spawning()
    test_direct_subprocess()
