#!/usr/bin/env python3
"""
Comprehensive diagnostic script to identify the source of the permission error
"""

import os
import sys
import django
import logging
from django.db import connection, transaction
from django.contrib.auth.models import Permission
from users.models import CustomUser

# Setup Django for production
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'branch_system.settings')
django.setup()

# Setup logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def check_table_structure():
    """Check the current table structure"""
    logger.info("Checking table structures...")
    
    with connection.cursor() as cursor:
        # Check users_user_permissions
        cursor.execute("DESCRIBE users_user_permissions")
        columns = cursor.fetchall()
        logger.info("users_user_permissions structure:")
        for col in columns:
            logger.info(f"  {col[0]}: {col[1]} {col[2]} {col[3]} {col[4]} {col[5]}")
        
        # Check users_groups
        cursor.execute("DESCRIBE users_groups")
        columns = cursor.fetchall()
        logger.info("users_groups structure:")
        for col in columns:
            logger.info(f"  {col[0]}: {col[1]} {col[2]} {col[3]} {col[4]} {col[5]}")

def test_direct_sql_insert():
    """Test direct SQL insert to identify the exact error"""
    logger.info("Testing direct SQL insert...")
    
    try:
        with connection.cursor() as cursor:
            # Get a user and permission
            user = CustomUser.objects.first()
            permission = Permission.objects.first()
            
            if not user or not permission:
                logger.error("No user or permission found for testing")
                return False
            
            logger.info(f"Testing with user: {user.username} (ID: {user.id})")
            logger.info(f"Testing with permission: {permission.name} (ID: {permission.id})")
            
            # Test direct insert
            cursor.execute("""
                INSERT INTO users_user_permissions (customuser_id, permission_id) 
                VALUES (%s, %s)
            """, [str(user.id), permission.id])
            
            logger.info("✅ Direct SQL insert successful")
            
            # Clean up
            cursor.execute("""
                DELETE FROM users_user_permissions 
                WHERE customuser_id = %s AND permission_id = %s
            """, [str(user.id), permission.id])
            
            logger.info("✅ Test record cleaned up")
            return True
            
    except Exception as e:
        logger.error(f"❌ Direct SQL insert failed: {e}")
        return False

def test_django_orm():
    """Test Django ORM operations"""
    logger.info("Testing Django ORM operations...")
    
    try:
        user = CustomUser.objects.first()
        permission = Permission.objects.first()
        
        if not user or not permission:
            logger.error("No user or permission found for testing")
            return False
        
        # Test adding permission
        logger.info("Testing user.user_permissions.add()...")
        user.user_permissions.add(permission)
        logger.info("✅ Permission added successfully")
        
        # Check if it was actually added
        user_permissions = user.user_permissions.all()
        logger.info(f"User now has {user_permissions.count()} permissions")
        
        # Test removing permission
        logger.info("Testing user.user_permissions.remove()...")
        user.user_permissions.remove(permission)
        logger.info("✅ Permission removed successfully")
        
        # Verify it was removed
        user_permissions = user.user_permissions.all()
        logger.info(f"User now has {user_permissions.count()} permissions")
        
        return True
        
    except Exception as e:
        logger.error(f"❌ Django ORM test failed: {e}")
        import traceback
        traceback.print_exc()
        return False

def test_bulk_operations():
    """Test bulk permission operations"""
    logger.info("Testing bulk permission operations...")
    
    try:
        user = CustomUser.objects.first()
        permissions = Permission.objects.all()[:3]
        
        if not user or not permissions.exists():
            logger.error("No user or permissions found for testing")
            return False
        
        # Test bulk add
        logger.info("Testing bulk add...")
        user.user_permissions.set(permissions)
        logger.info("✅ Bulk add successful")
        
        # Check count
        user_permissions = user.user_permissions.all()
        logger.info(f"User now has {user_permissions.count()} permissions")
        
        # Test bulk clear
        logger.info("Testing bulk clear...")
        user.user_permissions.clear()
        logger.info("✅ Bulk clear successful")
        
        # Check count
        user_permissions = user.user_permissions.all()
        logger.info(f"User now has {user_permissions.count()} permissions")
        
        return True
        
    except Exception as e:
        logger.error(f"❌ Bulk operations test failed: {e}")
        import traceback
        traceback.print_exc()
        return False

def check_django_settings():
    """Check Django settings that might affect permissions"""
    logger.info("Checking Django settings...")
    
    from django.conf import settings
    
    # Check AUTH_USER_MODEL
    logger.info(f"AUTH_USER_MODEL: {settings.AUTH_USER_MODEL}")
    
    # Check database settings
    db_settings = settings.DATABASES['default']
    logger.info(f"Database engine: {db_settings['ENGINE']}")
    logger.info(f"Database name: {db_settings['NAME']}")
    
    # Check if we're using the right user model
    from django.contrib.auth import get_user_model
    UserModel = get_user_model()
    logger.info(f"Active user model: {UserModel}")
    
    return True

def check_migration_status():
    """Check Django migration status"""
    logger.info("Checking migration status...")
    
    try:
        from django.core.management import call_command
        from io import StringIO
        
        # Capture migration status
        out = StringIO()
        call_command('showmigrations', 'users', stdout=out)
        migration_output = out.getvalue()
        
        logger.info("Users app migration status:")
        for line in migration_output.split('\n'):
            if line.strip():
                logger.info(f"  {line}")
        
        return True
        
    except Exception as e:
        logger.error(f"❌ Could not check migration status: {e}")
        return False

def test_specific_error_scenario():
    """Test the specific scenario that's causing the error"""
    logger.info("Testing specific error scenario...")
    
    try:
        # This is the exact operation that was failing
        user = CustomUser.objects.first()
        permission = Permission.objects.first()
        
        if not user or not permission:
            logger.error("No user or permission found for testing")
            return False
        
        logger.info("Testing the exact operation that was failing...")
        
        # Try the operation that was failing
        with transaction.atomic():
            user.user_permissions.add(permission)
            logger.info("✅ Transaction successful")
        
        # Clean up
        user.user_permissions.remove(permission)
        logger.info("✅ Cleanup successful")
        
        return True
        
    except Exception as e:
        logger.error(f"❌ Specific error scenario failed: {e}")
        import traceback
        traceback.print_exc()
        return False

def main():
    """Main diagnostic function"""
    logger.info("=" * 60)
    logger.info("COMPREHENSIVE PERMISSION ERROR DIAGNOSTIC")
    logger.info("=" * 60)
    
    tests = [
        ("Table Structure Check", check_table_structure),
        ("Django Settings Check", check_django_settings),
        ("Migration Status Check", check_migration_status),
        ("Direct SQL Insert Test", test_direct_sql_insert),
        ("Django ORM Test", test_django_orm),
        ("Bulk Operations Test", test_bulk_operations),
        ("Specific Error Scenario Test", test_specific_error_scenario),
    ]
    
    results = {}
    
    for test_name, test_func in tests:
        logger.info(f"\n--- Running {test_name} ---")
        try:
            result = test_func()
            results[test_name] = result
            if result:
                logger.info(f"✅ {test_name} PASSED")
            else:
                logger.error(f"❌ {test_name} FAILED")
        except Exception as e:
            logger.error(f"❌ {test_name} ERROR: {e}")
            results[test_name] = False
    
    # Summary
    logger.info("\n" + "=" * 60)
    logger.info("DIAGNOSTIC SUMMARY")
    logger.info("=" * 60)
    
    passed = sum(1 for result in results.values() if result)
    total = len(results)
    
    for test_name, result in results.items():
        status = "PASS" if result else "FAIL"
        logger.info(f"{test_name}: {status}")
    
    logger.info(f"\nOverall: {passed}/{total} tests passed")
    
    if passed == total:
        logger.info("🎉 All tests passed! The permission system should be working.")
    else:
        logger.error("❌ Some tests failed. Check the logs above for details.")
    
    return passed == total

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