#!/usr/bin/env python
"""
Test script to detect and reproduce session contamination bugs
Usage: docker exec igny8_backend python test_session_contamination.py
"""
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'igny8_core.settings')
django.setup()

from django.contrib.sessions.models import Session
from django.contrib.auth import get_user_model
from django.test import RequestFactory
from django.contrib.sessions.middleware import SessionMiddleware
from igny8_core.auth.middleware import AccountContextMiddleware
from datetime import datetime, timedelta

User = get_user_model()

def test_session_isolation():
    """Test that sessions are properly isolated between users"""
    print("\n=== SESSION CONTAMINATION TEST ===\n")
    
    # Get test users
    try:
        developer = User.objects.get(username='developer')
        scale_user = User.objects.filter(account__slug='scale-account').first()
        
        if not scale_user:
            print("⚠️  No scale account user found, creating one...")
            from igny8_core.auth.models import Account
            scale_account = Account.objects.filter(slug='scale-account').first()
            if scale_account:
                scale_user = User.objects.create_user(
                    username='scale_test',
                    email='scale@test.com',
                    password='testpass123',
                    account=scale_account,
                    role='owner'
                )
            else:
                print("❌ No scale account found")
                return False
        
        print(f"✓ Developer user: {developer.username} (account: {developer.account.slug})")
        print(f"✓ Scale user: {scale_user.username} (account: {scale_user.account.slug if scale_user.account else 'None'})")
        
    except Exception as e:
        print(f"❌ Failed to get test users: {e}")
        return False
    
    # Check active sessions
    active_sessions = Session.objects.filter(expire_date__gte=datetime.now())
    print(f"\n📊 Total active sessions: {active_sessions.count()}")
    
    # Count sessions by user
    user_sessions = {}
    for session in active_sessions:
        try:
            data = session.get_decoded()
            user_id = data.get('_auth_user_id')
            if user_id:
                user = User.objects.get(id=user_id)
                key = f"{user.username} ({user.account.slug if user.account else 'no-account'})"
                user_sessions[key] = user_sessions.get(key, 0) + 1
        except:
            pass
    
    print("\n📈 Sessions by user:")
    for user_key, count in sorted(user_sessions.items(), key=lambda x: x[1], reverse=True):
        print(f"   {user_key}: {count} sessions")
    
    # Check for session contamination patterns
    contamination_found = False
    
    # Pattern 1: Too many sessions for one user
    for user_key, count in user_sessions.items():
        if count > 20:
            print(f"\n⚠️  WARNING: {user_key} has {count} sessions (possible proliferation)")
            contamination_found = True
    
    # Pattern 2: Check session cookie settings
    from django.conf import settings
    print(f"\n🔧 Session Configuration:")
    print(f"   SESSION_COOKIE_NAME: {settings.SESSION_COOKIE_NAME}")
    print(f"   SESSION_COOKIE_DOMAIN: {getattr(settings, 'SESSION_COOKIE_DOMAIN', 'Not set (good)')}")
    print(f"   SESSION_COOKIE_SAMESITE: {getattr(settings, 'SESSION_COOKIE_SAMESITE', 'Not set')}")
    print(f"   SESSION_COOKIE_HTTPONLY: {settings.SESSION_COOKIE_HTTPONLY}")
    print(f"   SESSION_ENGINE: {settings.SESSION_ENGINE}")
    
    if getattr(settings, 'SESSION_COOKIE_SAMESITE', None) != 'Strict':
        print(f"\n⚠️  WARNING: SESSION_COOKIE_SAMESITE should be 'Strict' (currently: {getattr(settings, 'SESSION_COOKIE_SAMESITE', 'Not set')})")
        contamination_found = True
    
    # Test middleware isolation
    print(f"\n🧪 Testing Middleware Isolation...")
    factory = RequestFactory()
    
    # Simulate two requests from different users
    request1 = factory.get('/api/v1/test/')
    request1.user = developer
    request1.session = {}
    
    request2 = factory.get('/api/v1/test/')
    request2.user = scale_user
    request2.session = {}
    
    middleware = AccountContextMiddleware(lambda x: None)
    
    # Process requests
    middleware.process_request(request1)
    middleware.process_request(request2)
    
    # Check isolation
    account1 = getattr(request1, 'account', None)
    account2 = getattr(request2, 'account', None)
    
    print(f"   Request 1 account: {account1.slug if account1 else 'None'}")
    print(f"   Request 2 account: {account2.slug if account2 else 'None'}")
    
    if account1 and account2 and account1.id == account2.id:
        print(f"\n❌ CONTAMINATION DETECTED: Both requests have same account!")
        contamination_found = True
    else:
        print(f"\n✓ Middleware isolation working correctly")
    
    # Final result
    if contamination_found:
        print(f"\n❌ SESSION CONTAMINATION DETECTED")
        print(f"\nRecommended fixes:")
        print(f"1. Set SESSION_COOKIE_SAMESITE='Strict' in settings.py")
        print(f"2. Clear all existing sessions: Session.objects.all().delete()")
        print(f"3. Ensure users logout and re-login with fresh cookies")
        return False
    else:
        print(f"\n✅ No contamination detected - sessions appear isolated")
        return True

if __name__ == '__main__':
    result = test_session_isolation()
    exit(0 if result else 1)
