import features
from controllers.types import Agents, Nudges
from tests.conftest import fresh
from tests.kit import nudges, report


def test_chat_that_talks_about_the_journal_is_named_back_and_the_skill_is_always_loaded():
    from engine import chat
    from features.skill_loading.catalogue import primary
    features.load()
    record = fresh()
    report(record, "working", "PreToolUse")
    agent = Agents(record, actor="system").by_session("claude-1")
    chat.send(record, agent, 'The build is green; it now catches lines like "your message is answered".')
    chat.send(record, agent, "Released 2.85.18. A new message came in, so I'm reading it:")
    chat.send(record, agent, "Your message is answered. Now the terminal view.")
    chat.send(record, agent, "You reacted to the test-suite result. Nothing else is waiting.")
    assert [n for n in nudges(record) if "journal's workings" in n] == \
        ['your chat talked about the journal\'s workings - "A new message came in"',
         'your chat talked about the journal\'s workings - "Your message is answered"',
         'your chat talked about the journal\'s workings - "You reacted"'], \
        "only the turn about the journal's workings is named back"
    from features.chat_etiquette.handlers import SHOP_TALK
    assert [SHOP_TALK.search(text).group(0) for text in ("Message 4636 is answered. Continuing.",
                                                          "The replies to messages 4749, 4750 went out, but they're still listed as waiting.",
                                                          "Closing both explicitly:")] == \
        ["Message 4636 is answered", "replies to messages 4749, 4750 went out", "Closing both explicitly"], \
        "the state of the user's rows is not news either"
    assert SHOP_TALK.search("To-do 1013 trims the log; the reply hint is in the brief.") is None, "naming a row and its work is fine"
    assert SHOP_TALK.search("plus journal-todos once to-do 1024 is done") is None, "and so is naming what happens once a row is done"
    assert [bool(SHOP_TALK.search(text)) for text in ("Ik lees je bericht eerst.", "Bericht 12 is al beantwoord.", "De pagina is klaar.")] == [True, True, False], \
        "talk about the journal is caught in Dutch too, and plain Dutch about the work is not"
    assert "journal-chat-etiquette" in primary(), "its skill is loaded at every start, like the journal's own"
    record.set_setting("form_of_address", {"first_name": "Ada"})
    for line in ("Sir Ada asks to shorten the description.", "The user wants a shorter list.", "Will do, Sir Ada: shortening it now.",
                 'Your words were "Ada wants a list", so here it is.'):
        chat.send(record, agent, line)
    assert [n for n in nudges(record) if "instead of to them" in n] == \
        ['your chat spoke about the user instead of to them - "Sir Ada asks"', 'your chat spoke about the user instead of to them - "The user wants"'], \
        "talking about the user in the third person is named back; addressing them by name, or quoting, is not"


def test_every_twentieth_journal_line_reminds_the_agent_of_chat_etiquette():
    from engine import ran
    features.load()
    record = fresh()
    report(record, "working", "PreToolUse")
    agent = Agents(record, actor="system").by_session("claude-1")
    reminded = lambda: [n for n in nudges(record) if n.startswith("chat etiquette")]
    for _ in range(19):
        ran.announce(record, agent.n, ran.DELIVERED, "2 new messages 314, 315")
    assert not reminded(), "nineteen journal lines pass without a reminder"
    ran.announce(record, agent.n, ran.DELIVERED, "todo 5 next")
    assert len(reminded()) == 1, "the twentieth reminds the agent that a journal line is acted on or noted, never answered in the chat"
    told = [n.brief for n in Nudges(record).all() if n.title.startswith("chat etiquette")][0]
    assert ("needs no words" in told, "[!internal]" in told) == (True, False), "it says a turn for a journal line needs no words, and teaches no tag"
