"""Tests for the PII Detection Module."""

import pytest
from contextguard.pii import PIIDetector, _luhn_check


@pytest.fixture
def detector():
    return PIIDetector()


class TestPIIDetector:
    """Test suite for PIIDetector."""

    def test_clean_text(self, detector):
        result = detector.detect("The weather is nice today.")
        assert not result.is_detected
        assert result.score == 0.0

    def test_email_detection(self, detector):
        result = detector.detect("Contact me at john.doe@example.com")
        assert result.is_detected
        assert "email_address" in result.labels

    def test_phone_number(self, detector):
        result = detector.detect("Call me at (555) 123-4567")
        assert result.is_detected
        assert "phone_number" in result.labels

    def test_credit_card_visa(self, detector):
        # Valid Visa test number
        result = detector.detect("Card: 4111 1111 1111 1111")
        assert result.is_detected
        assert "credit_card" in result.labels

    def test_credit_card_invalid_luhn(self, detector):
        # Invalid card number (fails Luhn)
        result = detector.detect("Card: 4111 1111 1111 1112")
        assert "credit_card" not in result.labels

    def test_ip_address(self, detector):
        result = detector.detect("Server at 192.168.1.100")
        assert result.is_detected
        assert "ip_address" in result.labels

    def test_ssn(self, detector):
        result = detector.detect("SSN: 123-45-6789")
        assert result.is_detected
        assert "ssn" in result.labels

    def test_multiple_pii(self, detector):
        text = "Email: test@example.com, Phone: 555-123-4567, IP: 10.0.0.1"
        result = detector.detect(text)
        assert result.is_detected
        assert len(result.matches) >= 3

    def test_redaction_email(self, detector):
        result = detector.detect("john@example.com")
        assert result.redaction_map
        redacted = list(result.redaction_map.values())[0]
        assert "***" in redacted
        assert "@" in redacted

    def test_redaction_phone(self, detector):
        result = detector.detect("Call 555-123-4567")
        assert result.redaction_map
        for redacted in result.redaction_map.values():
            assert "***" in redacted

    def test_custom_pattern(self):
        custom = [("employee_id", r"EMP-\d{6}", 0.5)]
        detector = PIIDetector(custom_patterns=custom)
        result = detector.detect("Employee EMP-123456 report")
        assert result.is_detected
        assert "employee_id" in result.labels


class TestLuhnCheck:
    def test_valid_visa(self):
        assert _luhn_check("4111111111111111")

    def test_valid_mastercard(self):
        assert _luhn_check("5500000000000004")

    def test_invalid(self):
        assert not _luhn_check("4111111111111112")

    def test_too_short(self):
        assert not _luhn_check("12345")
