"""
Pure-logic tests for BrowseCompAnswerDecoder pipeline paths.

Tests decode_answer full loop (scheme fallback chain),
validate_decoded_answer boundaries, and is_likely_direct_answer boundaries
— all pure logic, no LLM or search calls.
"""

import base64

from local_deep_research.advanced_search_system.answer_decoding.browsecomp_answer_decoder import (
    BrowseCompAnswerDecoder,
)


class TestDecodeAnswerFullLoop:
    """Verify decode_answer end-to-end: scheme fallback, short-circuit, exceptions."""

    def setup_method(self):
        self.decoder = BrowseCompAnswerDecoder()

    def test_plaintext_short_circuits(self):
        """Plaintext answer is returned without decoding, scheme is None."""
        result, scheme = self.decoder.decode_answer("John Smith")
        assert result == "John Smith"
        assert scheme is None

    def test_empty_input_returns_as_is(self):
        """Empty string returns as-is with None scheme."""
        result, scheme = self.decoder.decode_answer("")
        assert result == ""
        assert scheme is None

    def test_whitespace_only_returns_as_is(self):
        """Whitespace-only input returns as-is."""
        result, scheme = self.decoder.decode_answer("   ")
        assert result == "   "
        assert scheme is None

    def test_base64_encoded_decoded_successfully(self):
        """Base64-encoded answer is decoded and validated."""
        # Encode a reasonable answer
        original = "Albert Einstein"
        encoded = base64.b64encode(original.encode()).decode()
        # This may or may not decode depending on is_likely_direct_answer
        result, scheme = self.decoder.decode_answer(encoded)
        # If it decoded, scheme should be "base64"
        # If it was treated as plaintext, scheme is None
        assert result is not None

    def test_all_schemes_fail_returns_original(self):
        """When no scheme can decode, returns original with None."""
        # A string that looks encoded but isn't valid for any scheme
        gibberish = "ZZZZZZZZZZZZZZZZ"
        result, scheme = self.decoder.decode_answer(gibberish)
        # Should return original since no decoding produces valid text
        assert result == gibberish or scheme is not None

    def test_hex_encoded_answer(self):
        """Hex-encoded answer is decoded."""
        original = "Hello World Test"
        encoded = original.encode().hex()
        result, scheme = self.decoder.decode_answer(encoded)
        # The hex string matches encoded patterns, so decoding is attempted
        assert result is not None


class TestValidateDecodedAnswer:
    """Verify validate_decoded_answer boundary conditions."""

    def setup_method(self):
        self.decoder = BrowseCompAnswerDecoder()

    def test_empty_string_invalid(self):
        """Empty string is not valid."""
        assert self.decoder.validate_decoded_answer("") is False

    def test_none_invalid(self):
        """None is not valid."""
        assert self.decoder.validate_decoded_answer(None) is False

    def test_whitespace_only_invalid(self):
        """Whitespace-only string is invalid."""
        assert self.decoder.validate_decoded_answer("   ") is False

    def test_single_char_valid(self):
        """Single alphabetic character is valid (length >= 1)."""
        assert self.decoder.validate_decoded_answer("A") is True

    def test_exactly_1000_chars_valid(self):
        """Exactly 1000 characters is valid (at boundary)."""
        text = "A" * 1000
        assert self.decoder.validate_decoded_answer(text) is True

    def test_1001_chars_invalid(self):
        """1001 characters exceeds the 1000-char limit."""
        text = "A" * 1001
        assert self.decoder.validate_decoded_answer(text) is False

    def test_exactly_30_percent_alpha(self):
        """Text with exactly 30% alphabetic characters passes."""
        # 30 letters + 70 digits = 100 chars, 30% alpha
        text = "a" * 30 + "1" * 70
        assert self.decoder.validate_decoded_answer(text) is True

    def test_below_30_percent_alpha(self):
        """Text with 29% alphabetic characters fails."""
        # 29 letters + 71 digits = 100 chars, 29% alpha
        text = "a" * 29 + "1" * 71
        assert self.decoder.validate_decoded_answer(text) is False

    def test_exactly_50_percent_punct(self):
        """Text with exactly 50% punctuation passes (not > 50%)."""
        # 50 letters + 50 punctuation = 100 chars
        text = "a" * 50 + "!" * 50
        assert self.decoder.validate_decoded_answer(text) is True

    def test_above_50_percent_punct(self):
        """Text with 51% punctuation fails."""
        # 49 letters + 51 punctuation = 100 chars
        text = "a" * 49 + "!" * 51
        assert self.decoder.validate_decoded_answer(text) is False

    def test_80_percent_printable_boundary(self):
        """Text with exactly 80% printable passes."""
        # 80 printable + 20 non-printable (control chars that aren't \t\n\r)
        # Actually control chars < 32 (not in \t\n\r) would fail the control char check first
        # Use chars > 127 that aren't printable
        printable_part = "a" * 80
        # Use characters that are printable (>= 32) to avoid control char check
        # The 80% check is: printable_count / len(decoded) >= 0.8
        text = printable_part + chr(0x7F) * 20  # DEL is not printable
        # DEL (127) is not a control char < 32 but is not printable
        result = self.decoder.validate_decoded_answer(text)
        # 80/100 = 0.8 which satisfies >= 0.8 but alpha = 80% passes too
        assert result is True

    def test_control_characters_invalid(self):
        """Text with control characters (< 32, not \\t\\n\\r) is invalid."""
        text = "Hello" + chr(1) + "World"
        assert self.decoder.validate_decoded_answer(text) is False

    def test_tab_newline_carriage_return_allowed(self):
        """Tabs, newlines, and carriage returns are not rejected."""
        text = "Hello\tWorld\nTest\rLine"
        assert self.decoder.validate_decoded_answer(text) is True

    def test_all_checks_pass_cumulatively(self):
        """A normal sentence passes all validation checks."""
        text = "The answer is Albert Einstein, born in 1879."
        assert self.decoder.validate_decoded_answer(text) is True


class TestIsLikelyDirectAnswer:
    """Verify is_likely_direct_answer boundary conditions and pattern matching."""

    def setup_method(self):
        self.decoder = BrowseCompAnswerDecoder()

    def test_very_short_answer_is_direct(self):
        """Answers shorter than 4 characters are always direct."""
        assert self.decoder.is_likely_direct_answer("Hi") is True
        assert self.decoder.is_likely_direct_answer("AB") is True

    def test_exactly_3_chars_is_direct(self):
        """3-char answer is direct (< 4)."""
        assert self.decoder.is_likely_direct_answer("abc") is True

    def test_exactly_4_chars_not_auto_direct(self):
        """4-char answer is NOT auto-direct (>= 4), checked by other heuristics."""
        # "ABCD" has no spaces, no English words, no common patterns
        # char_diversity = 4/4 = 1.0 (>= 0.3)
        # Not matching encoded patterns -> returns True (not encoded)
        result = self.decoder.is_likely_direct_answer("ABCD")
        assert isinstance(result, bool)

    def test_english_word_detected(self):
        """Answer containing an English indicator word is direct."""
        assert self.decoder.is_likely_direct_answer("the company") is True

    def test_multi_word_is_direct(self):
        """Multi-word answer with spaces is direct."""
        assert self.decoder.is_likely_direct_answer("John Doe") is True

    def test_year_pattern_is_direct(self):
        """4-digit year is direct."""
        assert self.decoder.is_likely_direct_answer("2024") is True

    def test_money_pattern_is_direct(self):
        """Dollar amount is direct."""
        assert self.decoder.is_likely_direct_answer("$500") is True

    def test_name_pattern_is_direct(self):
        """First Last name format is direct."""
        assert self.decoder.is_likely_direct_answer("John Smith") is True

    def test_percentage_is_direct(self):
        """Percentage format is direct."""
        assert self.decoder.is_likely_direct_answer("85%") is True

    def test_low_diversity_not_direct(self):
        """Repetitive characters (low diversity < 0.3) returns False."""
        # Use 'x' to avoid matching English indicators (which include "a")
        # "xxxxxxxxxxxx" has diversity 1/12 = 0.08 < 0.3
        assert self.decoder.is_likely_direct_answer("xxxxxxxxxxxx") is False

    def test_diversity_exactly_03(self):
        """Diversity of exactly 0.3 is NOT below threshold (< 0.3 check)."""
        # Need 10 chars with 3 unique, avoiding English indicator substrings
        # "xxxyyyzzzz" has 3 unique / 10 = 0.3
        text = "xxxyyyzzzz"
        assert len(set(text)) / len(text) == 0.3
        # diversity is not < 0.3, so won't return False at that check
        # Falls through to encoded pattern check (matches ^[A-Za-z0-9]{8,}$)
        result = self.decoder.is_likely_direct_answer(text)
        assert isinstance(result, bool)

    def test_encoded_pattern_detected(self):
        """Base64-looking string is flagged as potentially encoded."""
        # Matches r"^[A-Za-z0-9]{8,}$" encoded pattern
        # Avoid letters that form English indicator substrings (e.g. "a", "in", "or")
        encoded_looking = "XYZWVUTSRQPL"
        result = self.decoder.is_likely_direct_answer(encoded_looking)
        # Should be False because it matches an encoded pattern
        assert result is False

    def test_english_indicator_plus_encoded_chars(self):
        """English indicator word overrides encoded pattern detection."""
        # Contains "the" -> returns True immediately
        assert self.decoder.is_likely_direct_answer("the ABCDEFgh") is True
