"""High-value tests for BrowseCompAnswerDecoder internal scoring/validation methods."""

import pytest

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


@pytest.fixture
def decoder():
    return BrowseCompAnswerDecoder()


# --- _caesar_shift tests ---


class TestCaesarShift:
    def test_shift_zero(self, decoder):
        assert decoder._caesar_shift("abc", 0) == "abc"

    def test_shift_one_lowercase(self, decoder):
        assert decoder._caesar_shift("abc", 1) == "bcd"

    def test_shift_one_uppercase(self, decoder):
        assert decoder._caesar_shift("ABC", 1) == "BCD"

    def test_wraparound_lowercase(self, decoder):
        assert decoder._caesar_shift("xyz", 3) == "abc"

    def test_wraparound_uppercase(self, decoder):
        assert decoder._caesar_shift("XYZ", 3) == "ABC"

    def test_non_alpha_passthrough(self, decoder):
        assert decoder._caesar_shift("a1!b", 1) == "b1!c"

    def test_shift_25(self, decoder):
        assert decoder._caesar_shift("b", 25) == "a"

    def test_shift_13_rot13(self, decoder):
        assert decoder._caesar_shift("hello", 13) == "uryyb"

    def test_mixed_case_and_symbols(self, decoder):
        assert decoder._caesar_shift("Hello, World!", 5) == "Mjqqt, Btwqi!"

    def test_empty_string(self, decoder):
        assert decoder._caesar_shift("", 10) == ""


# --- _english_score tests ---


class TestEnglishScore:
    def test_empty_text(self, decoder):
        assert decoder._english_score("") == 0.0

    def test_no_letters(self, decoder):
        assert decoder._english_score("12345!@#") == 0.0

    def test_common_letters_high_score(self, decoder):
        score = decoder._english_score("the rain in spain")
        assert score > 0.5

    def test_uncommon_letters_lower_score(self, decoder):
        score_common = decoder._english_score("the")
        score_uncommon = decoder._english_score("zqx")
        assert score_common > score_uncommon

    def test_common_word_bonus(self, decoder):
        score_with_words = decoder._english_score("the cat is in the hat")
        score_without = decoder._english_score("blrk mnop qrst")
        assert score_with_words >= score_without

    def test_single_letter(self, decoder):
        score = decoder._english_score("e")
        assert score > 0.0

    def test_score_capped_at_one(self, decoder):
        score = decoder._english_score(
            "the and of to a in is it you that the and of to"
        )
        assert score <= 1.0


# --- validate_decoded_answer tests ---


class TestValidateDecodedAnswer:
    def test_empty_string_invalid(self, decoder):
        assert decoder.validate_decoded_answer("") is False

    def test_none_invalid(self, decoder):
        assert decoder.validate_decoded_answer(None) is False

    def test_whitespace_only_invalid(self, decoder):
        assert decoder.validate_decoded_answer("   ") is False

    def test_length_one_valid(self, decoder):
        # Single alpha character: length ok, 100% printable, 100% alpha, 0% punct
        assert decoder.validate_decoded_answer("A") is True

    def test_length_1000_valid(self, decoder):
        text = "Hello world " * 83 + "Hello wo"  # 1000 chars
        text = text[:1000]
        assert len(text.strip()) <= 1000
        assert decoder.validate_decoded_answer(text) is True

    def test_length_1001_invalid(self, decoder):
        text = "a" * 1001
        assert decoder.validate_decoded_answer(text) is False

    def test_low_printable_ratio_invalid(self, decoder):
        # Mostly non-printable (control chars with ord > 31 won't trigger ctrl check,
        # but let's use non-printable surrogates - actually just use many non-printable)
        text = "ab" + "\x00" * 10  # has control chars
        assert decoder.validate_decoded_answer(text) is False

    def test_control_characters_invalid(self, decoder):
        text = "Hello\x01World"
        assert decoder.validate_decoded_answer(text) is False

    def test_tab_newline_allowed(self, decoder):
        text = "Hello\tWorld\nFoo Bar"
        assert decoder.validate_decoded_answer(text) is True

    def test_low_alpha_ratio_invalid(self, decoder):
        text = "1234567890!@#$%^&*()"
        assert decoder.validate_decoded_answer(text) is False

    def test_high_punctuation_ratio_invalid(self, decoder):
        text = "a!@#$%^&*()!@#$%^&*()"
        assert decoder.validate_decoded_answer(text) is False

    def test_normal_text_valid(self, decoder):
        assert decoder.validate_decoded_answer("Mount Everest") is True


# --- is_likely_direct_answer tests ---


class TestIsLikelyDirectAnswer:
    def test_short_answer_plaintext(self, decoder):
        assert decoder.is_likely_direct_answer("Yes") is True

    def test_three_char_plaintext(self, decoder):
        assert decoder.is_likely_direct_answer("No!") is True

    def test_english_indicator_the(self, decoder):
        assert decoder.is_likely_direct_answer("the company") is True

    def test_english_indicator_corporation(self, decoder):
        assert decoder.is_likely_direct_answer("Acme Corporation") is True

    def test_multi_word_plaintext(self, decoder):
        assert decoder.is_likely_direct_answer("John Smith") is True

    def test_year_pattern(self, decoder):
        assert decoder.is_likely_direct_answer("2024") is True

    def test_money_pattern(self, decoder):
        assert decoder.is_likely_direct_answer("$500") is True

    def test_name_format_pattern(self, decoder):
        assert decoder.is_likely_direct_answer("John Smith") is True

    def test_low_char_diversity_not_plaintext(self, decoder):
        # Repetitive characters: needs >= 4 chars, no English indicators,
        # no spaces, no common patterns, and diversity < 0.3
        # "xzxzxzxzxzxzxzxz" -> diversity = 2/16 = 0.125 < 0.3
        # No English indicators match (no "the", "and", "a", etc. as substrings -
        # but "a" matches as substring! Use chars that avoid all indicators)
        result = decoder.is_likely_direct_answer("qxqxqxqxqxqxqxqx")
        assert result is False

    def test_encoded_base64_pattern(self, decoder):
        # Looks like base64: long string of alphanumeric + /+= chars
        result = decoder.is_likely_direct_answer("Y00Qhep12345")
        assert result is False

    def test_percentage_pattern(self, decoder):
        assert decoder.is_likely_direct_answer("75%") is True


# --- analyze_answer_encoding tests ---


class TestAnalyzeAnswerEncoding:
    def test_returns_dict_with_required_keys(self, decoder):
        result = decoder.analyze_answer_encoding("Hello")
        assert "original" in result
        assert "length" in result
        assert "likely_plaintext" in result
        assert "pattern_matches" in result
        assert "attempted_decodings" in result

    def test_plaintext_analysis(self, decoder):
        result = decoder.analyze_answer_encoding("Mount Everest")
        assert result["likely_plaintext"] is True
        assert result["original"] == "Mount Everest"
        assert result["length"] == 13

    def test_encoded_pattern_matches(self, decoder):
        # Hex-like string
        result = decoder.analyze_answer_encoding("48656c6c6f")
        matches = result["pattern_matches"]
        types = [m["type"] for m in matches]
        assert "hex" in types

    def test_attempted_decodings_all_schemes(self, decoder):
        result = decoder.analyze_answer_encoding("SGVsbG8=")
        assert "base64" in result["attempted_decodings"]
        assert "rot13" in result["attempted_decodings"]
        assert "caesar_cipher" in result["attempted_decodings"]

    def test_base64_decoded_valid(self, decoder):
        result = decoder.analyze_answer_encoding("SGVsbG8=")
        b64 = result["attempted_decodings"]["base64"]
        assert b64["decoded"] == "Hello"
        assert b64["valid"] is True
