"""Emotion-tag parsing for expressive TTS. A ``[감정]`` tag must steer the
pitch/speed of the text that follows without being spoken; a bracket that is NOT
a known emotion word must be kept as ordinary spoken content."""

from wsai.backends.emotion import (
    EMOTION_PARAMS,
    match_emotion,
    parse_segments,
)
from wsai.dashboard import _speech_text

BASE = 1.3


def test_emotion_tag_is_not_spoken_and_sets_delivery():
    segs = parse_segments("[기쁨] 오늘 날씨 좋다", BASE)
    assert len(segs) == 1
    assert "기쁨" not in segs[0].text        # the tag word is dropped
    assert segs[0].text == "오늘 날씨 좋다"
    mult, semis = EMOTION_PARAMS["happy"]
    assert segs[0].speed == BASE * mult
    assert segs[0].pitch == semis


def test_midreply_emotion_change_splits_segments():
    segs = parse_segments("[속상함] 정말 힘들었겠다. [힘차게] 하지만 넌 할 수 있어!", BASE)
    assert len(segs) == 2
    assert segs[0].text == "정말 힘들었겠다."
    assert segs[1].text == "하지만 넌 할 수 있어!"
    assert segs[0].pitch == EMOTION_PARAMS["sad"][1]
    assert segs[1].pitch == EMOTION_PARAMS["hopeful"][1]


def test_non_emotion_bracket_is_spoken_without_brackets():
    segs = parse_segments("[기쁨] 첫째는 [1번] 항목이야", BASE)
    assert len(segs) == 1
    # "1번" is not an emotion -> read it; brackets themselves are gone.
    assert "1번" in segs[0].text
    assert "[" not in segs[0].text and "]" not in segs[0].text
    assert segs[0].pitch == EMOTION_PARAMS["happy"][1]


def test_text_before_first_tag_is_neutral():
    segs = parse_segments("잠깐만. [신남] 찾았다!", BASE)
    assert segs[0].text == "잠깐만."
    assert segs[0].speed == BASE and segs[0].pitch == 0.0
    assert segs[1].pitch == EMOTION_PARAMS["excited"][1]


def test_plain_text_is_one_neutral_segment():
    segs = parse_segments("그냥 평범한 문장이야", BASE)
    assert len(segs) == 1
    assert segs[0].speed == BASE and segs[0].pitch == 0.0


def test_empty_input_yields_no_segments():
    assert parse_segments("", BASE) == []
    assert parse_segments("   ", BASE) == []


def test_only_emotion_tags_yield_no_segments():
    # A reply that is nothing but tags has nothing to say.
    assert parse_segments("[기쁨][신남]", BASE) == []


def test_match_emotion_is_synonym_and_space_tolerant():
    assert match_emotion("속상함") == "sad"
    assert match_emotion(" 힘 차게 ") == "hopeful"   # squeezed + trimmed
    assert match_emotion("행복하게") == "happy"
    assert match_emotion("메모") is None            # not an emotion


def test_persona_examples_are_all_recognised():
    # Every emotion the brain persona advertises must resolve, or it would be
    # read aloud instead of shaping the voice.
    for word in ["힘차게", "궁금", "반가움", "차분하게", "웃으며", "속상함"]:
        assert match_emotion(word) is not None, word


def test_voice_turn_keeps_leading_emotion_tag_for_tts_parser():
    text = "[속상함] 정말 힘들었겠다. [힘차게] 하지만 넌 할 수 있어!"

    spoken = _speech_text(text)
    segs = parse_segments(spoken, BASE)

    assert spoken == text
    assert segs[0].text == "정말 힘들었겠다."
    assert segs[0].pitch == EMOTION_PARAMS["sad"][1]
    assert segs[1].text == "하지만 넌 할 수 있어!"
    assert segs[1].pitch == EMOTION_PARAMS["hopeful"][1]
