"""Tests for strip.redact() and strip.rehydrate()."""

import pytest
from stripllm import StripLLM


@pytest.fixture
def strip():
    return StripLLM()


class TestRedactEmails:
    def test_single_email(self, strip):
        redacted, mapping = strip.redact("Contact john@example.com for details.")
        assert "john@example.com" not in redacted
        assert "[EMAIL_1]" in redacted
        assert mapping["[EMAIL_1]"] == "john@example.com"

    def test_multiple_emails(self, strip):
        redacted, mapping = strip.redact("From: alice@acme.com To: bob@corp.org")
        assert "alice@acme.com" not in redacted
        assert "bob@corp.org" not in redacted
        assert len([k for k in mapping if k.startswith("[EMAIL_")]) == 2

    def test_no_email(self, strip):
        redacted, mapping = strip.redact("No sensitive data here.")
        assert redacted == "No sensitive data here."
        assert mapping == {}


class TestRedactPhones:
    def test_us_phone_dashes(self, strip):
        redacted, mapping = strip.redact("Call me at 555-867-5309.")
        assert "555-867-5309" not in redacted
        assert "[PHONE_1]" in redacted

    def test_us_phone_parens(self, strip):
        redacted, mapping = strip.redact("My number is (415) 555-1234.")
        assert "(415) 555-1234" not in redacted


class TestRedactSSN:
    def test_ssn_with_dashes(self, strip):
        redacted, mapping = strip.redact("SSN: 123-45-6789")
        assert "123-45-6789" not in redacted
        assert "[SSN_1]" in redacted

    def test_ssn_with_spaces(self, strip):
        redacted, mapping = strip.redact("Social security: 234 56 7890")
        assert "234 56 7890" not in redacted


class TestRedactCreditCards:
    def test_visa_card(self, strip):
        redacted, mapping = strip.redact("Card: 4111111111111111")
        assert "4111111111111111" not in redacted
        assert "[CREDIT_CARD_1]" in redacted


class TestRedactEntityFilter:
    def test_email_only_filter(self, strip):
        text = "Email: user@test.com Phone: 555-123-4567"
        redacted, mapping = strip.redact(text, entities=["EMAIL"])
        assert "user@test.com" not in redacted
        assert "555-123-4567" in redacted  # phone not redacted

    def test_phone_only_filter(self, strip):
        text = "Email: user@test.com Phone: 555-123-4567"
        redacted, mapping = strip.redact(text, entities=["PHONE"])
        assert "user@test.com" in redacted  # email not redacted
        assert "555-123-4567" not in redacted


class TestRehydrate:
    def test_rehydrate_restores_original(self, strip):
        original = "Email me at john@acme.com for the invoice."
        redacted, mapping = strip.redact(original)
        restored = strip.rehydrate(redacted, mapping)
        assert "john@acme.com" in restored

    def test_rehydrate_multiple_entities(self, strip):
        original = "Contact alice@test.com or 555-123-4567."
        redacted, mapping = strip.redact(original)
        restored = strip.rehydrate(redacted, mapping)
        assert "alice@test.com" in restored

    def test_rehydrate_empty_mapping(self, strip):
        text = "No PII here."
        result = strip.rehydrate(text, {})
        assert result == "No PII here."

    def test_rehydrate_unknown_placeholder_preserved(self, strip):
        result = strip.rehydrate("Hello [EMAIL_99]", {})
        assert "[EMAIL_99]" in result
