"""OpenAI 式消息链校验与裁剪（避免 tool_calls / tool 错位导致 API 400）。"""

from __future__ import annotations

from aicd.agent.chat_context import (
    longest_valid_openai_suffix,
    openai_message_list_valid,
    repair_openai_chat_messages,
)


def _a(tc_ids: list[str]) -> dict:
    return {
        "role": "assistant",
        "content": "",
        "tool_calls": [
            {"id": tid, "type": "function", "function": {"name": "x", "arguments": "{}"}}
            for tid in tc_ids
        ],
    }


def _t(tid: str) -> dict:
    return {"role": "tool", "tool_call_id": tid, "content": "{}"}


def test_valid_user_assistant_tool_chain() -> None:
    msgs = [
        {"role": "user", "content": "u"},
        _a(["1"]),
        _t("1"),
        {"role": "assistant", "content": "done"},
    ]
    assert openai_message_list_valid(msgs)


def test_invalid_orphan_tool_prefix() -> None:
    msgs = [_t("1"), {"role": "user", "content": "u"}]
    assert not openai_message_list_valid(msgs)


def test_invalid_assistant_tc_without_tools() -> None:
    msgs = [{"role": "user", "content": "u"}, _a(["1", "2"]), _t("1")]
    assert not openai_message_list_valid(msgs)


def test_repair_drops_incomplete_tool_round() -> None:
    msgs = [{"role": "user", "content": "u"}, _a(["a", "b"]), _t("a")]
    repair_openai_chat_messages(msgs)
    assert msgs == [{"role": "user", "content": "u"}]


def test_longest_suffix_keeps_complete_round() -> None:
    body = [
        {"role": "user", "content": "old"},
        _a(["x"]),
        _t("x"),
        {"role": "user", "content": "new"},
        _a(["y"]),
        _t("y"),
    ]
    # 盲目 tail[-3:] 会得到 [user new, assistant(y), tool(y)] — 合法
    # 若窗口切断 assistant(x) 与 tool(x)，则非法；最长合法后缀应含完整 x 轮或仅 new 轮
    su = longest_valid_openai_suffix(body, 3)
    assert openai_message_list_valid(su)
    assert len(su) == 3
    assert su[0]["content"] == "new"


def test_longest_suffix_avoids_split_tool_round() -> None:
    """模拟子 Agent：尾部为 assistant(两工具) + 仅 1 条 tool；max_len=2 时不能取这 2 条。"""
    body = [
        {"role": "user", "content": "u"},
        _a(["p1", "p2"]),
        _t("p1"),
    ]
    su = longest_valid_openai_suffix(body, 2)
    assert openai_message_list_valid(su)
    assert len(su) == 1
    assert su[0]["role"] == "user"

