"""
Tests for services/quality/sampler.py
"""
import pytest

from services.quality.sampler import sample_chunks_for_l1


class TestSampleChunksForL1:
    def test_empty_chunks(self):
        result = sample_chunks_for_l1([], [], set(), max_samples=5, min_chunks=10)
        assert result == []

    def test_too_few_chunks(self):
        sources = ["Hello", "World", "Goodbye"]
        translations = ["Bonjour", "Monde", "Au revoir"]
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=5, min_chunks=10)
        # Only 3 chunks, min_chunks=10 → no sample
        assert result == []

    def test_min_chunks_exact(self):
        sources = ["chunk"] * 10
        translations = ["morceau"] * 10
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=5, min_chunks=10)
        # Exactly 10 chunks, min_chunks=10 → should sample
        assert len(result) == 5

    def test_skips_l0_failures(self):
        sources = ["a" * 100, "b" * 200, "c" * 300, "d" * 400]
        translations = ["x" * 100, "y" * 200, "z" * 300, "w" * 400]
        # Mark index 0 and 2 as L0 failures
        result = sample_chunks_for_l1(sources, translations, {0, 2},
                                       max_samples=10, min_chunks=3)
        sources_returned = [s for s, t in result]
        assert sources_returned == ["b" * 200, "d" * 400]

    def test_prefers_longest_chunks(self):
        # 10 chunks of different lengths. Each chunk has a unique marker
        # so we can verify which were picked regardless of whitespace.
        sources = [f"src{i}_" + "x" * (i * 5) for i in range(10)]
        translations = [f"tr{i}_" + "y" * (i * 5) for i in range(10)]
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=3, min_chunks=5)
        # The 3 longest should be picked (indices 9, 8, 7)
        assert len(result) == 3
        # Verify the longest chunks were picked
        markers_returned = [s for s, t in result]
        assert any("src9_" in s for s in markers_returned)
        assert any("src8_" in s for s in markers_returned)
        assert any("src7_" in s for s in markers_returned)
        # And the shortest were NOT picked
        assert not any("src0_" in s for s in markers_returned)
        assert not any("src1_" in s for s in markers_returned)

    def test_skips_identical_source_translation(self):
        # Identical pairs are probably numbers, codes, brand names
        sources = ["12345", "Hello", "WORLD"]
        translations = ["12345", "Bonjour", "WORLD"]
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=5, min_chunks=3)
        # "12345" and "WORLD" pairs should be skipped (identical)
        sources_returned = [s for s, t in result]
        assert "12345" not in sources_returned
        assert "WORLD" not in sources_returned
        assert "Hello" in sources_returned

    def test_skips_very_short_pairs(self):
        # Very short pairs don't have enough context
        sources = ["a", "Hello world this is a longer test sentence",
                   "b", "Another longer sentence for testing purposes"]
        translations = ["x", "Bonjour le monde ceci est une phrase plus longue",
                        "y", "Une autre phrase plus longue pour tester"]
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=5, min_chunks=2)
        # The "a"/"x" and "b"/"y" pairs should be skipped
        sources_returned = [s for s, t in result]
        assert "a" not in sources_returned
        assert "b" not in sources_returned
        assert len(result) == 2

    def test_respects_max_samples(self):
        sources = [f"long source {i} " * 10 for i in range(20)]
        translations = [f"long translation {i} " * 10 for i in range(20)]
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=3, min_chunks=5)
        assert len(result) == 3

    def test_results_in_document_order(self):
        # The function should return in original document order,
        # not in the length-priority order. (Use .strip()-friendly data
        # to avoid whitespace edge cases in equality.)
        sources = ["short source 1", "long source 2 " * 20, "medium source 3 " * 10, "tiny source 4"]
        translations = ["court 1", "longue 2 " * 20, "moyen 3 " * 10, "minuscule 4"]
        result = sample_chunks_for_l1(sources, translations, set(),
                                       max_samples=4, min_chunks=2)
        # Indices in the result should be 0, 1, 2, 3 (in document order)
        for i, (s, t) in enumerate(result):
            assert s == sources[i].strip(), f"Source {i} mismatch: {s!r} vs {sources[i].strip()!r}"
            assert t == translations[i].strip(), f"Translation {i} mismatch"
