"""微信 4.x .dat 文件 XOR 解密逻辑的单测。

覆盖 DbReader._decrypt_dat 的三个最小用例：
- PNG（key=0x3A）
- JPEG（key=0xE5）
- 纯文本（key=0x00，无法推导时回退原密文）
"""

from __future__ import annotations

import os
import sys

# 将 bridge/ 目录加入 sys.path，使 woc_bridge 包可被导入
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from woc_bridge.db.reader import DbReader


def _xor(data: bytes, key: int) -> bytes:
    """对 data 逐字节异或 key，构造密文。"""
    return bytes(b ^ key for b in data)


def test_png_key_0x3a():
    """PNG magic 0x89 50 4E 47 ... XOR 0x3A，解密后首字节应为 0x89。"""
    plaintext = b"\x89PNG\r\n\x1a\n" + b"\x00" * 16
    ciphertext = _xor(plaintext, 0x3A)

    result = DbReader._decrypt_dat(ciphertext)

    assert result is not None, "PNG 密文应能推导出 key"
    decrypted, mime = result
    assert decrypted[0] == 0x89
    assert decrypted == plaintext
    assert mime == "image/png"


def test_jpeg_key_0xe5():
    """JPEG magic 0xFF D8 FF E0 XOR 0xE5，解密后首字节应为 0xFF。"""
    plaintext = b"\xff\xd8\xff\xe0" + b"\x00" * 16
    ciphertext = _xor(plaintext, 0xE5)

    result = DbReader._decrypt_dat(ciphertext)

    assert result is not None, "JPEG 密文应能推导出 key"
    decrypted, mime = result
    assert decrypted[0] == 0xFF
    assert decrypted == plaintext
    assert mime == "image/jpeg"


def test_plaintext_key_0x00_fallback():
    """纯文本 'Hello' XOR 0x00（即原文），无 magic 命中应回退原密文。

    key=0x00 时密文即原文 'Hello'，其首字节 0x48 不属于任何图片 magic，
    故 _decrypt_dat 返回 None，由调用方回退原密文返回。
    """
    plaintext = b"Hello"
    ciphertext = _xor(plaintext, 0x00)  # 等于原文

    result = DbReader._decrypt_dat(ciphertext)

    # 推导失败 → 返回 None（调用方据此回退原密文）
    assert result is None, "纯文本无 magic 命中应返回 None 触发回退"
    # 回退路径下，调用方返回的密文应与原文一致
    assert ciphertext == plaintext
