from __future__ import annotations

import io
import zipfile
from pathlib import Path

import pytest

from turbo_agent_core.schema.enums import FileType, KnowledgeType
from turbo_agent_core.utils.file_types import parse_knowledge_file_type, validate_upload_file_signature


PNG_BYTES = (
    b"\x89PNG\r\n\x1a\n"
    b"\x00\x00\x00\rIHDR"
    b"\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00"
    b"\x1f\x15\xc4\x89"
)


def test_parse_knowledge_file_type_uses_python_library_detection_for_binary_file() -> None:
    parsed = parse_knowledge_file_type("application/octet-stream", "avatar.image", file_bytes=PNG_BYTES)

    assert parsed.file_type == FileType.png
    assert parsed.knowledge_type == KnowledgeType.Picture
    assert parsed.mime_type == "image/png"
    assert parsed.filename == "avatar.png"
    assert parsed.detected_mime_type == "image/png"


def test_parse_knowledge_file_type_uses_extension_when_library_cannot_detect_text() -> None:
    parsed = parse_knowledge_file_type("text/plain", "notes.md", file_bytes=b"# hello\n")

    assert parsed.file_type == FileType.md
    assert parsed.knowledge_type == KnowledgeType.Document
    assert parsed.mime_type == "text/markdown"
    assert parsed.filename == "notes.md"


def test_parse_knowledge_file_type_can_detect_from_file_path(tmp_path: Path) -> None:
    sample_file = tmp_path / "cover.unknown"
    sample_file.write_bytes(PNG_BYTES)

    parsed = parse_knowledge_file_type(None, sample_file.name, file_path=str(sample_file))

    assert parsed.file_type == FileType.png
    assert parsed.knowledge_type == KnowledgeType.Picture
    assert parsed.mime_type == "image/png"
    assert parsed.filename == "cover.png"


def test_validate_upload_file_signature_rejects_declared_mime_conflict() -> None:
    parsed = validate_upload_file_signature("application/pdf", "avatar.png", file_bytes=PNG_BYTES)

    assert parsed.mime_type == "image/png"
    assert parsed.filename == "avatar.png"


def test_validate_upload_file_signature_rejects_extension_conflict() -> None:
    parsed = validate_upload_file_signature("image/png", "avatar.pdf", file_bytes=PNG_BYTES)

    assert parsed.mime_type == "image/png"
    assert parsed.filename == "avatar.png"


def test_validate_upload_file_signature_allows_zip_archive() -> None:
    zip_buffer = io.BytesIO()
    with zipfile.ZipFile(zip_buffer, "w", compression=zipfile.ZIP_DEFLATED) as archive:
        archive.writestr("notes.txt", "hello zip")

    parsed = validate_upload_file_signature("application/zip", "bundle.zip", file_bytes=zip_buffer.getvalue())

    assert parsed.filename == "bundle.zip"
    assert parsed.detected_mime_type == "application/zip"


def test_validate_upload_file_signature_rejects_unsupported_binary_type() -> None:
    with pytest.raises(ValueError, match="无法识别上传文件的真实类型|当前不支持该上传文件类型"):
        validate_upload_file_signature(None, "payload.bin", file_bytes=b"\x00\x01\x02\x03\x04\x05")