"""Tests for text chunking module."""
import pytest

from greymatter_core.chunking import chunk_text


def test_short_text_returns_single_chunk():
    """Text shorter than chunk_size should return one chunk."""
    text = "This is a short text."
    chunks = chunk_text(text, chunk_size=1500, overlap=200)
    assert len(chunks) == 1
    assert chunks[0] == text


def test_empty_text_returns_empty_list():
    """Empty or None text should return empty list."""
    assert chunk_text("", chunk_size=1500, overlap=200) == []
    assert chunk_text(None, chunk_size=1500, overlap=200) == []


def test_long_text_splits_into_overlapping_chunks():
    """Long text should be split with overlap between adjacent chunks."""
    paragraphs = [f"Paragraph {i}. " * 20 for i in range(10)]
    text = "\n\n".join(paragraphs)
    chunks = chunk_text(text, chunk_size=500, overlap=100)
    assert len(chunks) > 1
    for c in chunks:
        assert len(c) <= 600
    for i in range(len(chunks) - 1):
        tail = chunks[i][-50:]
        assert tail in chunks[i + 1]


def test_splits_at_paragraph_boundary():
    """Chunking should prefer paragraph boundaries."""
    text = "First paragraph content here." + "\n\n" + "Second paragraph starts here."
    chunks = chunk_text(text, chunk_size=35, overlap=5)
    assert len(chunks) >= 2
    assert chunks[0].rstrip().endswith("here.")


def test_splits_at_sentence_boundary():
    """When no paragraph boundary, split at sentence boundary."""
    text = "First sentence here. Second sentence here. Third sentence here. Fourth sentence here."
    chunks = chunk_text(text, chunk_size=50, overlap=10)
    assert len(chunks) >= 2
    for c in chunks[:-1]:
        assert c.rstrip().endswith(".")


def test_splits_at_whitespace_when_no_sentence_boundary():
    """When no paragraph or sentence boundary, split at whitespace."""
    text = "word " * 300  # no periods, no paragraphs
    chunks = chunk_text(text, chunk_size=100, overlap=20)
    assert len(chunks) > 1
    for c in chunks:
        # Each chunk should end at a word boundary
        assert c == c.rstrip() or c.endswith(" ")


def test_hard_cut_when_no_whitespace():
    """When no split points exist, hard cut at chunk_size."""
    text = "x" * 500  # no spaces, no punctuation
    chunks = chunk_text(text, chunk_size=100, overlap=20)
    assert len(chunks) > 1
    # All content preserved
    joined = "".join(chunks)
    assert "x" * 500 in joined or len(joined) >= 500


def test_never_splits_mid_word():
    """Chunks should never break in the middle of a word."""
    text = "abcdef " * 200
    chunks = chunk_text(text, chunk_size=100, overlap=20)
    for c in chunks:
        words = c.split()
        for w in words:
            assert w in text  # every word in chunk appears intact in original
