"""
Tests for Behavior Policy v2.1
Aligned with Global System Prompt v2.1 — FINAL

Tests cover:
- Broadcast detection
- Imperative/explicit request detection
- Mention detection
- SOWA: DM always responds
- SOWA: Mentioned + explicit_request -> responds
- SOWA: Broadcast without mention -> NO_OUTPUT
- SOWA: Media/link without request -> NO_OUTPUT
- SOWA: Media + mention -> responds
- SOWA: Bare mention in public -> NO_OUTPUT (v2.1 anti-spam)
- SOWA: Bare mention in DM -> responds
- SOWA: Question without mention in topic -> NO_OUTPUT
- URL detection
- Reply to agent
"""
import pytest
import sys
import os

# Add gateway-bot to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'gateway-bot'))

from behavior_policy import (
    analyze_message,
    should_respond,
    detect_agent_mention,
    detect_broadcast_intent,
    detect_question,
    detect_imperative,
    detect_url,
    detect_explicit_request,
    detect_short_note,
    detect_media_question,
)


# ===== Broadcast Detection =====

class TestBroadcastDetection:
    def test_time_pattern(self):
        assert detect_broadcast_intent("20:00 10.02 Deployed")

    def test_emoji_start(self):
        assert detect_broadcast_intent("\u26a1 Оновлення системи")

    def test_announcement_word(self):
        assert detect_broadcast_intent("увага всім! нова версія")

    def test_url_only(self):
        assert detect_broadcast_intent("https://example.com")

    def test_normal_message_not_broadcast(self):
        assert not detect_broadcast_intent("Допоможи з налаштуванням")


# ===== Imperative Detection =====

class TestImperativeDetection:
    def test_ua_imperative(self):
        assert detect_imperative("Допоможи з налаштуванням")

    def test_ua_analyze(self):
        assert detect_imperative("Проаналізуй логи")

    def test_en_fix(self):
        assert detect_imperative("Fix this bug")

    def test_en_explain(self):
        assert detect_imperative("Explain how it works")

    def test_no_imperative(self):
        assert not detect_imperative("Просто повідомлення")


# ===== Explicit Request Detection (Gateway level) =====

class TestExplicitRequestDetection:
    def test_imperative_triggers(self):
        assert detect_explicit_request("Допоможи з налаштуванням")

    def test_question_with_mention(self):
        assert detect_explicit_request("Що це?", mentioned_agents=['helion'])

    def test_question_in_dm(self):
        assert detect_explicit_request("Що це?", is_dm=True)

    def test_question_without_context(self):
        assert not detect_explicit_request("Що це?")

    def test_no_question_no_imperative(self):
        assert not detect_explicit_request("Просто текст без питання")


# ===== Question Detection =====

class TestQuestionDetection:
    def test_with_question_mark(self):
        assert detect_question("Що це таке?")

    def test_without_question_mark(self):
        assert not detect_question("Що нового в проекті")


# ===== Mention Detection =====

class TestMentionDetection:
    def test_helion_at_mention(self):
        assert detect_agent_mention("@Helion що на постері?", "helion")

    def test_helion_name(self):
        assert detect_agent_mention("Helion, допоможи", "helion")

    def test_ua_name(self):
        assert detect_agent_mention("хеліон, що скажеш?", "helion")

    def test_no_mention(self):
        assert not detect_agent_mention("Хто знає відповідь?", "helion")


# ===== URL Detection =====

class TestURLDetection:
    def test_https(self):
        assert detect_url("Check https://example.com")

    def test_www(self):
        assert detect_url("Visit www.github.com")

    def test_telegram(self):
        assert detect_url("Join t.me/channel")

    def test_telegram_me(self):
        assert detect_url("Link: telegram.me/bot")

    def test_no_link(self):
        assert not detect_url("No link here")


# ===== SOWA: DM Always Responds =====

class TestSOWADMAlwaysResponds:
    def test_dm_responds(self):
        decision = analyze_message(
            text="Привіт",
            agent_id="helion",
            chat_id="123",
            user_id="456",
            is_private_chat=True,
        )
        assert decision.should_respond
        assert decision.reason == "private_chat"


# ===== SOWA: Mentioned + Request =====

class TestSOWAMentionedWithRequest:
    def test_mentioned_with_request(self):
        decision = analyze_message(
            text="@Helion що змінилось у v2.0?",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            is_private_chat=False,
            payload_explicit_request=True,
        )
        assert decision.should_respond
        assert decision.reason == "mentioned_with_request"


# ===== SOWA: Broadcast Without Mention =====

class TestSOWABroadcastNoMention:
    def test_broadcast_no_mention(self):
        resp, reason = should_respond(
            text="\u26a1 Оновлення: релізимо v2.0",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            is_private_chat=False,
        )
        assert not resp
        assert reason == "broadcast_not_directed"


# ===== SOWA: Media Without Request =====

class TestSOWAMediaWithoutRequest:
    def test_media_no_request(self):
        resp, reason = should_respond(
            text="",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            has_media=True,
            is_private_chat=False,
            payload_explicit_request=False,
        )
        assert not resp
        assert reason == "media_or_link_without_request"


# ===== SOWA: Media + Mention =====

class TestSOWAMediaWithMention:
    def test_media_with_mention(self):
        decision = analyze_message(
            text="@Helion що на фото?",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            has_media=True,
            media_caption="@Helion що на фото?",
            is_private_chat=False,
            payload_explicit_request=True,
        )
        assert decision.should_respond
        assert decision.reason == "mentioned_with_request"


# ===== v2.1: Bare Mention in Public = NO_OUTPUT =====

class TestSOWABareMentionPublicNoResponse:
    def test_bare_mention_public(self):
        resp, reason = should_respond(
            text="@Helion",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            is_private_chat=False,
            payload_explicit_request=False,
        )
        assert not resp
        assert reason == "bare_mention_public_topic"


# ===== v2.1: Bare Mention in DM = Responds =====

class TestSOWABareMentionDMResponds:
    def test_bare_mention_dm(self):
        resp, reason = should_respond(
            text="@Helion",
            agent_id="helion",
            chat_id="123",
            user_id="456",
            is_private_chat=True,
            payload_explicit_request=False,
        )
        assert resp
        assert reason == "private_chat"


# ===== SOWA: Question Without Mention in Topic =====

class TestSOWAQuestionWithoutMentionInTopic:
    def test_question_no_mention_topic(self):
        resp, reason = should_respond(
            text="Хто знає чому падає сервер?",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            is_private_chat=False,
            payload_explicit_request=False,
        )
        assert not resp
        assert reason == "not_directed_to_agent"


# ===== SOWA: Reply to Agent =====

class TestSOWAReplyToAgent:
    def test_reply_to_agent(self):
        resp, reason = should_respond(
            text="А що з цим робити?",
            agent_id="helion",
            chat_id="-100123",
            user_id="456",
            is_private_chat=False,
            is_reply_to_agent=True,
        )
        assert resp
        assert reason == "reply_to_agent"


# ===== Short Notes =====

class TestShortNotes:
    def test_checkmark(self):
        assert detect_short_note("\u2705")

    def test_ok(self):
        assert detect_short_note("ok")

    def test_plus(self):
        assert detect_short_note("+")

    def test_normal_message(self):
        assert not detect_short_note("Це нормальне повідомлення")


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
