"""工作区对话型 agent 必须绑定工作文件夹的后端守卫测试。

防的是最坑的失败模式:无 ?dir → 静默回退 agent 空家目录 → 读不到用户文件
还以 completed 收尾(假装成功)。守卫把它变成显式 400 WORKSPACE_DIR_REQUIRED。
"""
from __future__ import annotations

import pytest
from fastapi import HTTPException

from agentpaas.api.v1.agents import _require_workspace_dir


class _Req:
    def __init__(self, ctx):
        self.context = ctx


def test_workspace_assistant_rejects_empty_context():
    agent = {"agent_template": "workspace.assistant"}
    with pytest.raises(HTTPException) as ei:
        _require_workspace_dir(agent, _Req({}))
    assert ei.value.status_code == 400
    assert ei.value.detail["code"] == "WORKSPACE_DIR_REQUIRED"


def test_workspace_assistant_rejects_nonexistent_dir():
    agent = {"agent_template": "workspace.assistant"}
    with pytest.raises(HTTPException):
        _require_workspace_dir(agent, _Req({"work_dir": "/no/such/dir/zzz_nope"}))


def test_workspace_assistant_accepts_valid_dir(tmp_path):
    agent = {"agent_template": "workspace.assistant"}
    # 有效目录 → 不抛
    _require_workspace_dir(agent, _Req({"work_dir": str(tmp_path)}))


def test_workspace_assistant_rejects_non_dict_context():
    agent = {"agent_template": "workspace.assistant"}
    with pytest.raises(HTTPException):
        _require_workspace_dir(agent, _Req(None))


def test_non_workspace_agent_unaffected():
    # 专项智能体不受此守卫约束(它们写各自 run 工作区)
    agent = {"agent_template": "research.top-journal-reviewer"}
    _require_workspace_dir(agent, _Req({}))  # 不抛
    _require_workspace_dir({"agent_template": ""}, _Req({}))  # 空模板也不抛


from agentpaas.api.v1.agents import _is_native_workspace


def test_native_lane_only_for_claude_code_provider():
    ws = {"agent_template": "workspace.assistant"}
    assert _is_native_workspace(ws, {"model": {"provider": "claude-code"}}) is True
    # 切到 qwen/ollama/openai → 退回 react 车道(native 跑不了非 claude 模型)
    assert _is_native_workspace(ws, {"model": {"provider": "dashscope", "name": "qwen-max"}}) is False
    assert _is_native_workspace(ws, {"model": {"provider": "ollama"}}) is False
    assert _is_native_workspace(ws, {"model": {}}) is False
    # 非工作区模板:永不走 native
    assert _is_native_workspace({"agent_template": "research.x"},
                                {"model": {"provider": "claude-code"}}) is False


from agentpaas.api.v1.agents import _resolve_session_cwd


def test_session_cwd_aligns_with_workdir_hint(tmp_path):
    """会话 CWD 必须 == [工作目录] 提示(overrides.workspace_path),否则相对写入落错目录
    (run_bf2405e28547:literature_map.md 落进 agent 家目录而非本 run 工作区)。"""
    F = tmp_path / "user_folder";  F.mkdir()
    ws = tmp_path / "run_xxx";     ws.mkdir()
    home = tmp_path / "agent_home"; home.mkdir()
    # 工作区对话模式:CWD = F
    assert _resolve_session_cwd(str(F), str(ws), str(home)) == str(F)
    # 专项 agent(无 inplace):CWD = 本 run workspace_path(修复点,原来错误地返回 work_dir)
    assert _resolve_session_cwd("", str(ws), str(home)) == str(ws)
    # 兜底:无 workspace_path → work_dir
    assert _resolve_session_cwd("", "", str(home)) == str(home)
    # inplace 无效路径被忽略,退回 workspace_path
    assert _resolve_session_cwd("/no/such/dir", str(ws), str(home)) == str(ws)
