#!/usr/bin/env python
"""
Test script for role permission validation system
Tests task 6.3: Create role permission validation system
"""

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

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

from django.contrib.auth import get_user_model
from users.models import CustomUser, Branch
from users.enhanced_permissions_models import PagePermission, RolePermissionTemplate
from users.services import RolePermissionTemplateManager
from django.db import transaction
import json

def test_role_permission_validation_system():
    """Test the enhanced role permission validation system"""
    
    print("🧪 Testing Role Permission Validation System")
    print("=" * 60)
    
    try:
        # Clean up existing test data
        print("\n1. Cleaning up existing test data...")
        CustomUser.objects.filter(username__startswith='test_').delete()
        PagePermission.objects.filter(page_name='test_page').delete()
        RolePermissionTemplate.objects.filter(role='loan_officer').delete()
        
        # Create test branch
        branch, _ = Branch.objects.get_or_create(
            name='Test Branch',
            defaults={'location': 'Test Location'}
        )
        
        # Create test admin user
        admin_user = CustomUser.objects.create_user(
            username='test_admin',
            email='admin@test.com',
            password='testpass123',
            role='admin',
            branch=branch,
            is_superuser=True,
            phone_number='0700000001'
        )
        
        # Create test permissions with dependencies
        print("\n2. Creating test permissions with dependencies...")
        test_permissions = [
            # Basic permissions
            {
                'page_name': 'loans',
                'action_code': 'loans_view_applications',
                'action_name': 'View Loan Applications',
                'description': 'Permission to view loan applications',
                'category': 'view',
                'is_critical': False
            },
            {
                'page_name': 'loans',
                'action_code': 'loans_edit_application',
                'action_name': 'Edit Loan Applications',
                'description': 'Permission to edit loan applications',
                'category': 'edit',
                'is_critical': False
            },
            # Critical permissions
            {
                'page_name': 'loans',
                'action_code': 'loans_approve_application',
                'action_name': 'Approve Loan Applications',
                'description': 'Permission to approve loan applications',
                'category': 'approve',
                'is_critical': True
            },
            {
                'page_name': 'loans',
                'action_code': 'loans_delete_application',
                'action_name': 'Delete Loan Applications',
                'description': 'Permission to delete loan applications',
                'category': 'delete',
                'is_critical': True
            },
            # Financial permissions
            {
                'page_name': 'loans',
                'action_code': 'loans_view_calculations',
                'action_name': 'View Loan Calculations',
                'description': 'Permission to view loan calculations',
                'category': 'view',
                'is_critical': True
            },
            # Client permissions
            {
                'page_name': 'clients',
                'action_code': 'clients_view_list',
                'action_name': 'View Client List',
                'description': 'Permission to view client list',
                'category': 'view',
                'is_critical': False
            },
            {
                'page_name': 'clients',
                'action_code': 'clients_delete_client',
                'action_name': 'Delete Clients',
                'description': 'Permission to delete clients',
                'category': 'delete',
                'is_critical': True
            },
            # Export permissions
            {
                'page_name': 'reports',
                'action_code': 'reports_export_excel',
                'action_name': 'Export Reports to Excel',
                'description': 'Permission to export reports to Excel',
                'category': 'export',
                'is_critical': False
            }
        ]
        
        created_permissions = []
        for perm_data in test_permissions:
            permission = PagePermission.objects.create(**perm_data)
            created_permissions.append(permission)
            print(f"✓ Created permission: {permission.action_name}")
        
        # Initialize role template manager
        template_manager = RolePermissionTemplateManager()
        
        # Test 1: Validate safe permission set
        print("\n3. Testing validation of safe permission set...")
        safe_permissions = {
            'loans': {
                'loans_view_applications': True,
                'loans_edit_application': False,
                'loans_approve_application': False,
                'loans_delete_application': False,
                'loans_view_calculations': False
            },
            'clients': {
                'clients_view_list': True,
                'clients_delete_client': False
            },
            'reports': {
                'reports_export_excel': False
            }
        }
        
        safe_validation = template_manager.validate_role_permission_set(
            role='loan_officer',
            permissions_dict=safe_permissions,
            strict_mode=False
        )
        
        print(f"✓ Safe permission validation completed")
        print(f"  - Valid: {safe_validation['valid']}")
        print(f"  - Severity: {safe_validation.get('severity', 'unknown')}")
        print(f"  - Critical permissions: {len(safe_validation.get('critical_permissions', []))}")
        print(f"  - Security concerns: {len(safe_validation.get('security_concerns', []))}")
        print(f"  - Warnings: {len(safe_validation.get('warnings', []))}")
        
        # Test 2: Validate dangerous permission combination
        print("\n4. Testing validation of dangerous permission combination...")
        dangerous_permissions = {
            'loans': {
                'loans_view_applications': True,
                'loans_edit_application': True,
                'loans_approve_application': True,  # Critical
                'loans_delete_application': True,   # Critical + dangerous combo
                'loans_view_calculations': True     # Critical + dangerous combo
            },
            'clients': {
                'clients_view_list': True,
                'clients_delete_client': True      # Critical + dangerous combo
            },
            'reports': {
                'reports_export_excel': True       # Part of dangerous combo
            }
        }
        
        dangerous_validation = template_manager.validate_role_permission_set(
            role='secretary',  # Secretary shouldn't have these permissions
            permissions_dict=dangerous_permissions,
            strict_mode=True
        )
        
        print(f"✓ Dangerous permission validation completed")
        print(f"  - Valid: {dangerous_validation['valid']}")
        print(f"  - Severity: {dangerous_validation.get('severity', 'unknown')}")
        print(f"  - Critical permissions: {len(dangerous_validation.get('critical_permissions', []))}")
        print(f"  - Security concerns: {len(dangerous_validation.get('security_concerns', []))}")
        print(f"  - Warnings: {len(dangerous_validation.get('warnings', []))}")
        
        for concern in dangerous_validation.get('security_concerns', []):
            print(f"    - {concern.get('type', 'unknown')}: {concern.get('warning', 'No description')}")
        
        # Test 3: Validate permission dependencies
        print("\n5. Testing permission dependency validation...")
        dependency_permissions = {
            'loans': {
                'loans_view_applications': False,   # Missing dependency
                'loans_edit_application': False,    # Missing dependency
                'loans_delete_application': True,   # Requires view and edit
                'loans_approve_application': True,  # Requires view
                'loans_view_calculations': False
            },
            'clients': {
                'clients_view_list': False,         # Missing dependency
                'clients_delete_client': True      # Requires view and edit
            }
        }
        
        dependency_validation = template_manager.validate_permission_dependencies(dependency_permissions)
        
        print(f"✓ Dependency validation completed")
        print(f"  - Valid: {dependency_validation['valid']}")
        print(f"  - Missing dependencies: {len(dependency_validation.get('missing_dependencies', []))}")
        
        for missing_dep in dependency_validation.get('missing_dependencies', []):
            print(f"    - {missing_dep['permission']} requires: {', '.join(missing_dep['missing'])}")
        
        # Test 4: Generate comprehensive validation report
        print("\n6. Testing comprehensive validation report generation...")
        report = template_manager.create_permission_validation_report(
            role='loan_officer',
            permissions_dict=dangerous_permissions,
            include_recommendations=True
        )
        
        print(f"✓ Validation report generated")
        print(f"  - Overall valid: {report['summary']['overall_valid']}")
        print(f"  - Total permissions: {report['summary']['total_permissions']}")
        print(f"  - Granted permissions: {report['summary']['granted_permissions']}")
        print(f"  - Risk level: {report['risk_assessment']['risk_level']}")
        print(f"  - Recommendations: {len(report.get('recommendations', []))}")
        
        for i, recommendation in enumerate(report.get('recommendations', [])[:3]):  # Show first 3
            print(f"    {i+1}. {recommendation['title']} (Priority: {recommendation['priority']})")
        
        # Test 5: Test role-specific validation rules
        print("\n7. Testing role-specific validation rules...")
        
        # Test auditor with write permissions (should trigger warnings)
        auditor_permissions = {
            'loans': {
                'loans_view_applications': True,
                'loans_create_application': True,   # Auditors shouldn't create
                'loans_approve_application': True,  # Auditors shouldn't approve
                'loans_delete_application': False
            },
            'clients': {
                'clients_view_list': True,
                'clients_create_new': True,         # Auditors shouldn't create
                'clients_delete_client': False
            }
        }
        
        auditor_validation = template_manager.validate_role_permission_set(
            role='auditor',
            permissions_dict=auditor_permissions
        )
        
        print(f"✓ Auditor role validation completed")
        print(f"  - Security concerns: {len(auditor_validation.get('security_concerns', []))}")
        print(f"  - Warnings: {len(auditor_validation.get('warnings', []))}")
        
        for concern in auditor_validation.get('security_concerns', []):
            if concern.get('type') == 'escalation_risk':
                print(f"    - Escalation risk: {', '.join(concern.get('risky_permissions', []))}")
        
        # Test 6: Test missing essential permissions
        print("\n8. Testing missing essential permissions detection...")
        incomplete_permissions = {
            'loans': {
                'loans_approve_application': True,  # Has approval but missing view
                'loans_delete_application': False
            }
            # Missing clients_view_list which is essential for loan_officer
        }
        
        incomplete_validation = template_manager.validate_role_permission_set(
            role='loan_officer',
            permissions_dict=incomplete_permissions
        )
        
        print(f"✓ Missing essential permissions validation completed")
        missing_essential = incomplete_validation.get('missing_required_permissions', [])
        print(f"  - Missing essential permissions: {len(missing_essential)}")
        if missing_essential:
            print(f"    - Missing: {', '.join(missing_essential)}")
        
        # Test 7: Test strict mode validation
        print("\n9. Testing strict mode validation...")
        strict_validation = template_manager.validate_role_permission_set(
            role='team_leader',
            permissions_dict=dangerous_permissions,
            strict_mode=True
        )
        
        print(f"✓ Strict mode validation completed")
        print(f"  - Severity: {strict_validation.get('severity', 'unknown')}")
        print(f"  - Additional warnings in strict mode: {len([w for w in strict_validation.get('warnings', []) if 'Strict mode' in w])}")
        
        print("\n" + "=" * 60)
        print("🎉 All role permission validation system tests completed successfully!")
        print("\nImplemented validation features:")
        print("✓ Comprehensive permission combination validation")
        print("✓ Critical permission dependency checking")
        print("✓ Dangerous permission combination detection")
        print("✓ Role-specific validation rules")
        print("✓ Permission escalation risk assessment")
        print("✓ Missing essential permissions detection")
        print("✓ Strict mode validation for high-security environments")
        print("✓ Comprehensive validation reporting with recommendations")
        print("✓ Risk level assessment and severity scoring")
        
        return True
        
    except Exception as e:
        print(f"\n❌ Test failed with error: {e}")
        import traceback
        traceback.print_exc()
        return False
    
    finally:
        # Clean up test data
        print("\n10. Cleaning up test data...")
        try:
            CustomUser.objects.filter(username__startswith='test_').delete()
            PagePermission.objects.filter(page_name__in=['loans', 'clients', 'reports']).delete()
            RolePermissionTemplate.objects.filter(role='loan_officer').delete()
            print("✓ Test data cleaned up")
        except Exception as e:
            print(f"⚠️  Warning: Could not clean up all test data: {e}")

if __name__ == '__main__':
    success = test_role_permission_validation_system()
    sys.exit(0 if success else 1)