"""Tests for Python bindings - data sanitization functionality"""

import pytest
import json
import briefcase_ai


class TestSanitizer:
    def test_sanitizer_creation(self):
        """Test Sanitizer creation"""
        sanitizer = briefcase_ai.Sanitizer()
        assert sanitizer is not None

    def test_disabled_sanitizer(self):
        """Test disabled Sanitizer"""
        sanitizer = briefcase_ai.Sanitizer.disabled()

        result = sanitizer.sanitize("test@email.com")
        assert result.sanitized == "test@email.com"
        assert len(result.redactions) == 0

    def test_email_sanitization(self):
        """Test email PII sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Contact me at john.doe@example.com for details."
        result = sanitizer.sanitize(text)

        assert "[REDACTED_EMAIL]" in result.sanitized
        assert len(result.redactions) == 1
        assert result.redactions[0].pii_type == "email"

    def test_ssn_sanitization(self):
        """Test SSN PII sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        # Test different SSN formats
        test_cases = [
            "My SSN is 123-45-6789.",
            "SSN: 123 45 6789",
            "SSN123456789"
        ]

        for text in test_cases:
            result = sanitizer.sanitize(text)
            assert "[REDACTED_SSN]" in result.sanitized
            assert len(result.redactions) >= 1

    def test_credit_card_sanitization(self):
        """Test credit card PII sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        test_cases = [
            "Card number: 4532-1234-5678-9012",
            "Card: 4532123456789012",
            "CC: 4532 1234 5678 9012"
        ]

        for text in test_cases:
            result = sanitizer.sanitize(text)
            assert "[REDACTED_CREDIT_CARD]" in result.sanitized

    def test_phone_sanitization(self):
        """Test phone number PII sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        test_cases = [
            "Call me at (555) 123-4567",
            "Phone: +1-555-123-4567",
            "Tel: 555.123.4567"
        ]

        for text in test_cases:
            result = sanitizer.sanitize(text)
            assert "[REDACTED_PHONE]" in result.sanitized

    def test_api_key_sanitization(self):
        """Test API key PII sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        test_cases = [
            "OpenAI key: sk-1234567890abcdef1234567890abcdef",
            "API key: api_1234567890abcdef",
            "Key: bai_1234567890abcdef"
        ]

        for text in test_cases:
            result = sanitizer.sanitize(text)
            assert "[REDACTED_API_KEY]" in result.sanitized

    def test_ip_address_sanitization(self):
        """Test IP address PII sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Server IP: 192.168.1.100"
        result = sanitizer.sanitize(text)

        assert "[REDACTED_IP]" in result.sanitized
        assert len(result.redactions) == 1

    def test_multiple_pii_sanitization(self):
        """Test sanitization of multiple PII types"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Contact john@example.com at 555-123-4567 or visit 192.168.1.100"
        result = sanitizer.sanitize(text)

        assert "[REDACTED_EMAIL]" in result.sanitized
        assert "[REDACTED_PHONE]" in result.sanitized
        assert "[REDACTED_IP]" in result.sanitized
        assert len(result.redactions) == 3

    def test_custom_pattern(self):
        """Test adding custom PII pattern"""
        sanitizer = briefcase_ai.Sanitizer()

        # Add custom pattern for employee ID
        sanitizer.add_pattern("employee_id", r"\bEMP-\d{6}\b")

        text = "Employee ID: EMP-123456"
        result = sanitizer.sanitize(text)

        assert "[REDACTED_EMPLOYEE_ID]" in result.sanitized

    def test_remove_pattern(self):
        """Test removing PII pattern"""
        sanitizer = briefcase_ai.Sanitizer()

        # Remove email pattern
        removed = sanitizer.remove_pattern("email")
        assert removed

        # Email should no longer be redacted
        text = "Email: test@example.com"
        result = sanitizer.sanitize(text)
        assert result.sanitized == text

    def test_enable_disable(self):
        """Test enabling/disabling sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Email: test@example.com"

        # Disable sanitization
        sanitizer.set_enabled(False)
        result = sanitizer.sanitize(text)
        assert result.sanitized == text

        # Re-enable sanitization
        sanitizer.set_enabled(True)
        result = sanitizer.sanitize(text)
        assert "[REDACTED_EMAIL]" in result.sanitized

    def test_sanitize_json(self):
        """Test JSON sanitization"""
        sanitizer = briefcase_ai.Sanitizer()

        data = {
            "user": {
                "email": "john@example.com",
                "phone": "555-123-4567"
            },
            "config": {
                "api_key": "sk-1234567890abcdef1234567890abcdef",
                "timeout": 30
            }
        }

        result = sanitizer.sanitize_json(data)

        assert result.sanitized["user"]["email"] == "[REDACTED_EMAIL]"
        assert result.sanitized["user"]["phone"] == "[REDACTED_PHONE]"
        assert result.sanitized["config"]["api_key"] == "[REDACTED_API_KEY]"
        assert result.sanitized["config"]["timeout"] == 30  # Number unchanged

        assert len(result.redactions) == 3

    def test_contains_pii(self):
        """Test PII detection without modification"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Email: john@example.com, Phone: 555-123-4567"
        matches = sanitizer.contains_pii(text)

        assert len(matches) == 2
        pii_types = [match.pii_type for match in matches]
        assert "email" in pii_types
        assert "phone" in pii_types

    def test_analyze(self):
        """Test PII analysis"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Contact john@example.com or jane@test.org at 555-123-4567"
        analysis = sanitizer.analyze(text)

        assert analysis.has_pii
        assert analysis.total_matches == 3
        assert analysis.unique_types == 2  # Email and Phone
        assert analysis.type_counts["email"] == 2
        assert analysis.type_counts["phone"] == 1

    def test_redaction_details(self):
        """Test redaction details and positions"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "My email is test@example.com and my phone is 555-123-4567"
        result = sanitizer.sanitize(text)

        # Check redaction details
        email_redaction = next(r for r in result.redactions if r.pii_type == "email")
        phone_redaction = next(r for r in result.redactions if r.pii_type == "phone")

        assert email_redaction.original_length > 0
        assert phone_redaction.original_length > 0
        assert email_redaction.start_position < email_redaction.end_position
        assert phone_redaction.start_position < phone_redaction.end_position

    def test_invalid_pattern(self):
        """Test adding invalid regex pattern"""
        sanitizer = briefcase_ai.Sanitizer()

        with pytest.raises(Exception):
            sanitizer.add_pattern("invalid", "[")  # Invalid regex

    def test_result_to_object(self):
        """Test SanitizationResult serialization"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Email: test@example.com"
        result = sanitizer.sanitize(text)
        obj = result.to_object()

        assert "sanitized" in obj
        assert "redactions" in obj
        assert obj["sanitized"] == result.sanitized

    def test_json_result_to_object(self):
        """Test SanitizationJsonResult serialization"""
        sanitizer = briefcase_ai.Sanitizer()

        data = {"email": "test@example.com", "count": 5}
        result = sanitizer.sanitize_json(data)
        obj = result.to_object()

        assert "sanitized" in obj
        assert "redactions" in obj

    def test_analysis_to_object(self):
        """Test PiiAnalysis serialization"""
        sanitizer = briefcase_ai.Sanitizer()

        text = "Email: test@example.com"
        analysis = sanitizer.analyze(text)
        obj = analysis.to_object()

        assert "has_pii" in obj
        assert "total_matches" in obj
        assert "unique_types" in obj
        assert "type_counts" in obj
        assert "matches" in obj


class TestSanitizationIntegration:
    def test_ai_model_data_protection(self):
        """Test protecting AI model training data"""
        sanitizer = briefcase_ai.Sanitizer()

        # Simulate training data with various PII
        training_examples = [
            "Customer john.doe@company.com reported issue with order #12345",
            "Support ticket: Call Sarah at (555) 123-4567 regarding account 123-45-6789",
            "API logs show requests from 192.168.1.100 using key sk-abc123def456",
            "User feedback: 'Great service! Contact me at jane@email.com for partnership.'"
        ]

        sanitized_examples = []
        total_redactions = 0

        for example in training_examples:
            result = sanitizer.sanitize(example)
            sanitized_examples.append(result.sanitized)
            total_redactions += len(result.redactions)

        # Verify all PII was removed
        assert total_redactions > 0
        for sanitized in sanitized_examples:
            assert "john.doe@company.com" not in sanitized
            assert "(555) 123-4567" not in sanitized
            assert "123-45-6789" not in sanitized
            assert "192.168.1.100" not in sanitized
            assert "sk-abc123def456" not in sanitized

    def test_logging_sanitization(self):
        """Test sanitizing application logs"""
        sanitizer = briefcase_ai.Sanitizer()

        # Add custom patterns for session IDs and user IDs
        sanitizer.add_pattern("session_id", r"session_[a-f0-9]{32}")
        sanitizer.add_pattern("user_id", r"user_\d{6}")

        log_entries = [
            "INFO: User user_123456 logged in with session session_abc123def456789012345678901234",
            "ERROR: Failed to send email to support@company.com from 10.0.0.1",
            "DEBUG: Processing payment 4532-1234-5678-9012 for user_789012",
        ]

        for log_entry in log_entries:
            result = sanitizer.sanitize(log_entry)

            # Verify sensitive data is redacted
            assert "user_123456" not in result.sanitized or "[REDACTED_USER_ID]" in result.sanitized
            assert "session_abc" not in result.sanitized or "[REDACTED_SESSION_ID]" in result.sanitized
            assert "support@company.com" not in result.sanitized or "[REDACTED_EMAIL]" in result.sanitized
            assert "4532-1234-5678-9012" not in result.sanitized or "[REDACTED_CREDIT_CARD]" in result.sanitized

    def test_configuration_data_sanitization(self):
        """Test sanitizing configuration files"""
        sanitizer = briefcase_ai.Sanitizer()

        config = {
            "database": {
                "host": "192.168.1.50",
                "port": 5432,
                "username": "admin"
            },
            "api": {
                "openai_key": "sk-1234567890abcdefghijklmnop",
                "anthropic_key": "sk-ant-api_key_123456789",
                "rate_limit": 1000
            },
            "notifications": {
                "admin_email": "admin@company.com",
                "sms_number": "555-123-4567"
            }
        }

        result = sanitizer.sanitize_json(config)

        # Verify sensitive fields are sanitized
        assert result.sanitized["database"]["host"] == "[REDACTED_IP]"
        assert result.sanitized["api"]["openai_key"] == "[REDACTED_API_KEY]"
        assert result.sanitized["notifications"]["admin_email"] == "[REDACTED_EMAIL]"

        # Verify non-sensitive fields remain unchanged
        assert result.sanitized["database"]["port"] == 5432
        assert result.sanitized["api"]["rate_limit"] == 1000

    def test_performance_large_dataset(self):
        """Test sanitization performance with large datasets"""
        sanitizer = briefcase_ai.Sanitizer()

        # Generate large text with scattered PII
        base_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
        large_text = base_text * 100 + " Contact: admin@test.com and phone: 555-123-4567"

        result = sanitizer.sanitize(large_text)

        # Should complete quickly and find PII
        assert "[REDACTED_EMAIL]" in result.sanitized
        assert "[REDACTED_PHONE]" in result.sanitized
        assert len(result.redactions) == 2

    def test_overlapping_patterns(self):
        """Test handling of overlapping PII patterns"""
        sanitizer = briefcase_ai.Sanitizer()

        # Add pattern that might overlap with SSN
        sanitizer.add_pattern("partial_ssn", r"\d{3}-\d{2}")

        text = "SSN: 123-45-6789"
        result = sanitizer.sanitize(text)

        # Should only redact once (longer pattern should win)
        assert len(result.redactions) == 1


if __name__ == "__main__":
    pytest.main([__file__])