from pathlib import Path
from unittest.mock import patch

from app.agent.tools.impl.transfer_file import TransferFileTool
from app.schemas.types import MediaType


def test_transfer_file_local_directory_without_trailing_slash_uses_dir(tmp_path):
    """本地目录路径即使没有尾斜杠，也应按目录交给整理链路。"""
    source_dir = tmp_path / "Movie Folder"
    source_dir.mkdir()
    captured = {}

    def _manual_transfer(self, **kwargs):
        """记录工具传给整理链路的参数。"""
        captured.update(kwargs)
        return True, None

    with patch(
        "app.chain.transfer.TransferChain.manual_transfer",
        new=_manual_transfer,
    ):
        result = TransferFileTool._transfer_file_sync(str(source_dir))

    assert result == f"整理成功：{source_dir}"
    assert captured["fileitem"].type == "dir"
    assert captured["fileitem"].path == str(source_dir)


def test_transfer_file_local_file_uses_file(tmp_path):
    """本地文件路径应继续按文件交给整理链路。"""
    source_file = tmp_path / "Movie.mkv"
    source_file.write_text("fake media", encoding="utf-8")
    captured = {}

    def _manual_transfer(self, **kwargs):
        """记录工具传给整理链路的参数。"""
        captured.update(kwargs)
        return True, None

    with patch(
        "app.chain.transfer.TransferChain.manual_transfer",
        new=_manual_transfer,
    ):
        result = TransferFileTool._transfer_file_sync(str(source_file))

    assert result == f"整理成功：{source_file}"
    assert captured["fileitem"].type == "file"
    assert captured["fileitem"].path == str(source_file)


def test_transfer_file_remote_directory_still_uses_trailing_slash():
    """远程存储无法用本地 stat 判断时，继续使用尾斜杠识别目录。"""
    captured = {}

    def _manual_transfer(self, **kwargs):
        """记录工具传给整理链路的参数。"""
        captured.update(kwargs)
        return True, None

    with patch(
        "app.chain.transfer.TransferChain.manual_transfer",
        new=_manual_transfer,
    ):
        result = TransferFileTool._transfer_file_sync(
            "downloads/Show/",
            storage="alist",
        )

    assert result == "整理成功：/downloads/Show/"
    assert captured["fileitem"].type == "dir"
    assert captured["fileitem"].path == "/downloads/Show/"


def test_transfer_file_remote_album_uses_entity_type_without_trailing_slash():
    """远程专辑路径应由显式 album 语义判定为目录。"""
    captured = {}

    def _manual_transfer(self, **kwargs):
        """记录工具传给整理链路的参数。"""
        captured.update(kwargs)
        return True, None

    with patch(
        "app.chain.transfer.TransferChain.manual_transfer",
        new=_manual_transfer,
    ):
        result = TransferFileTool._transfer_file_sync(
            "downloads/Jay/叶惠美",
            storage="alist",
            media_type="music",
            music_type="album",
            media_source="musicbrainz",
            media_id="release-group-1",
        )

    assert result == "整理成功：/downloads/Jay/叶惠美"
    assert captured["fileitem"].type == "dir"
    assert captured["mtype"] == MediaType.MUSIC
    assert captured["media_id"] == "release-group-1"


def test_transfer_file_rejects_recording_directory(tmp_path):
    """单曲实体不能覆盖一个目录，避免把整专误当成一首歌。"""
    source_dir = tmp_path / "Album"
    source_dir.mkdir()

    with patch("app.chain.transfer.TransferChain.manual_transfer") as manual_transfer:
        result = TransferFileTool._transfer_file_sync(
            str(source_dir),
            media_type="music",
            music_type="recording",
            media_source="musicbrainz",
            media_id="recording-1",
        )

    assert "单曲必须按一个音频文件整理" in result
    manual_transfer.assert_not_called()
