"""快速新对话自动标题的纯函数边界。"""
from __future__ import annotations

import unittest
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from uuid import uuid4

from core.task_title import (
    clean_generated_title,
    generate_task_title,
    is_attachment_only_message,
)


class TaskTitleTests(unittest.TestCase):
    def test_strips_model_wrappers_and_forbidden_path_chars(self):
        self.assertEqual(
            clean_generated_title('标题：“低碳水泥/XRD 分析”', "原消息"),
            "低碳水泥·XRD 分析",
        )

    def test_empty_or_generic_output_falls_back_to_user_message(self):
        self.assertEqual(
            clean_generated_title("新对话", "  分析熟料三率值变化\n补充说明"),
            "分析熟料三率值变化",
        )

    def test_title_is_bounded(self):
        title = clean_generated_title("这是一段非常非常长而且不适合作为对话标题的模型输出内容", "")
        self.assertLessEqual(len(title), 24)

    def test_attachment_only_message_is_deferred_for_auto_title(self):
        self.assertTrue(is_attachment_only_message(
            "[用户上传的参考图] 项目/显微照片.png\n[用户上传的文件] 项目/数据表.xlsx"
        ))
        self.assertFalse(is_attachment_only_message(
            "请分析这些数据\n\n[用户上传的文件] 项目/数据表.xlsx"
        ))
        self.assertFalse(is_attachment_only_message(""))

    def test_model_failure_applies_local_fallback_title(self):
        task_id = uuid4()
        user_id = uuid4()
        read_session = MagicMock()
        read_session.execute.return_value.first.return_value = SimpleNamespace(
            auto_title_pending=True,
            auto_title_version=3,
        )
        write_session = MagicMock()
        write_session.execute.return_value.rowcount = 1

        read_ctx = MagicMock()
        read_ctx.__enter__.return_value = read_session
        write_ctx = MagicMock()
        write_ctx.__enter__.return_value = write_session

        with (
            patch("core.task_title.session_scope", side_effect=[read_ctx, write_ctx]),
            patch(
                "core.task_title.load_config",
                return_value={
                    "default_model": "deepseek_v4.flash",
                    "models_dir": "config/models",
                },
            ),
            patch("core.task_title.ModelCapabilities.load", return_value=MagicMock()),
            patch("core.task_title.LLM", side_effect=RuntimeError("provider unavailable")),
        ):
            title = generate_task_title(
                task_id=task_id,
                user_id=user_id,
                user_message="分析手机端自动命名失败\n补充说明",
                model_profile="deepseek_v4.flash",
            )

        self.assertEqual(title, "分析手机端自动命名失败")
        values = write_session.execute.call_args.args[0].compile().params
        self.assertEqual(values["name"], "分析手机端自动命名失败")
        self.assertFalse(values["auto_title_pending"])


if __name__ == "__main__":
    unittest.main()
