"""Run locally with pytest test_chunk_practice.py or on the chapter page.

GUIDE and ANSWERS are the invented getting-started guide and its eight labelled answer
sentences from the chunking video."""

from chunk_practice import SLACK_ANSWER, fixed_chunks, answer_exists, whole_answer_first


def test_overlap_repeats_boundary_text():
    assert fixed_chunks("abcdefghij", 6, 2) == ["abcdef", "efghij", "ij"]
    assert fixed_chunks("abcdefghij", 6) == ["abcdef", "ghij"]


def test_invalid_step_cannot_loop_forever():
    for size, overlap in [(0, 0), (6, 6), (6, 7), (6, -1)]:
        try:
            fixed_chunks("abc", size, overlap)
        except ValueError:
            pass
        else:
            assert False, "invalid size or overlap must raise ValueError"


def test_right_guide_can_still_cut_the_slack_answer():
    cut = {"source": "guide", "text": "The Slack integration posts task updates to a channel yo"}
    assert not whole_answer_first([cut], SLACK_ANSWER)
    assert whole_answer_first([{"source": "guide", "text": SLACK_ANSWER}], SLACK_ANSWER)


def test_answer_exists_is_not_answer_first():
    chunks = ["Other topic", SLACK_ANSWER]
    assert answer_exists(chunks, SLACK_ANSWER)
    assert not whole_answer_first([{"source": "guide", "text": chunks[0]}, {"source": "guide", "text": chunks[1]}], SLACK_ANSWER)
    assert not answer_exists([], SLACK_ANSWER)
    assert not whole_answer_first([], SLACK_ANSWER)


GUIDE = "Welcome! This guide walks you through your first week. Start by creating a project: click New project in the sidebar and give it a name. Every project has a board with three columns to begin with, To do, In progress and Done, and you can rename or add columns at any time.\n\nYou don't have to start from a blank project. Pick a template when you create it: there are templates for product launches, content calendars, bug tracking and hiring, each with columns and example tasks already set up. You can also save any project as a template for your team.\n\nTasks are the cards on your board. Open a task to add a description, an assignee, labels and a due date. Drag a card between columns to change its status, or drag it up and down to change its priority.\n\nDue dates come with reminders. By default, you get a reminder one day before a task is due and another on the due date itself. You can change the timing for each task, or turn reminders off under Account Settings, then Notifications.\n\nKeyboard shortcuts make everyday work faster. Press N to create a new task, E to edit the selected one, and slash to search. Press the question mark key at any time to see the full list of shortcuts.\n\nComments keep discussion next to the work. Type the at sign followed by a teammate's name to mention them, and they get a notification right away. You can attach files to a comment, and react with an emoji instead of writing a reply.\n\nIntegrations connect your workspace to the tools you already use. The Slack integration posts task updates to a channel you choose. The Google Calendar integration shows due dates in your calendar. Turn integrations on under Workspace Settings, then Integrations.\n\nAutomations do repetitive work for you. A rule has a trigger and an action, for example: when a GitHub pull request is merged, move the linked task to Done. Rules are set up per project, under Project Settings, then Automations.\n\nFilters help you focus. Use the filter bar above the board to show only tasks assigned to you, tasks with a certain label, or tasks due this week. Save a filter as a view so you can come back to it in one click.\n\nWhen a project is finished, archive it instead of deleting it. Archived projects disappear from the sidebar but keep all their tasks, comments and files, and you can restore them at any time from Workspace Settings, then Archive.\n"
ANSWERS = [
    "Pick a template when you create it: there are templates for product launches, content calendars, bug tracking and hiring, each with columns and example tasks already set up.",
    "By default, you get a reminder one day before a task is due and another on the due date itself.",
    "Press N to create a new task, E to edit the selected one, and slash to search.",
    "The Slack integration posts task updates to a channel you choose.",
    "A rule has a trigger and an action, for example: when a GitHub pull request is merged, move the linked task to Done.",
    "Type the at sign followed by a teammate's name to mention them, and they get a notification right away.",
    "Use the filter bar above the board to show only tasks assigned to you, tasks with a certain label, or tasks due this week.",
    "Archived projects disappear from the sidebar but keep all their tasks, comments and files, and you can restore them at any time from Workspace Settings, then Archive."
]


def test_the_real_guide_at_300_characters():
    chunks = fixed_chunks(GUIDE, 300)
    assert len(chunks) == 8
    assert any(c.endswith("The Sl") for c in chunks)          # the cut through the Slack answer
    assert not answer_exists(chunks, SLACK_ANSWER)
    paragraphs = [p.strip() for p in GUIDE.split("\n\n") if p.strip()]
    assert len(paragraphs) == 10 and answer_exists(paragraphs, SLACK_ANSWER)


def test_overlap_moves_the_cuts():
    exists = {ov: sum(answer_exists(fixed_chunks(GUIDE, 300, ov), a) for a in ANSWERS) for ov in (0, 50, 150)}
    assert exists == {0: 6, 50: 3, 150: 8}   # 50 of overlap kept fewer answers whole at this size
