from backend.app.services.file_validator import (
    is_validatable,
    validate_file,
)


def test_is_validatable_only_known_extensions(tmp_path):
    assert is_validatable(tmp_path / "x.jpg")
    assert is_validatable(tmp_path / "x.JPEG")
    assert is_validatable(tmp_path / "x.png")
    assert is_validatable(tmp_path / "x.gif")
    assert is_validatable(tmp_path / "x.webp")
    assert not is_validatable(tmp_path / "x.json")
    assert not is_validatable(tmp_path / "x.mp4")


def test_valid_jpeg_passes(tmp_path):
    from PIL import Image
    p = tmp_path / "good.jpg"
    Image.new("RGB", (32, 32), (200, 50, 50)).save(p, "JPEG")
    r = validate_file(p)
    assert r.ok is True
    assert r.format == "jpeg"
    assert r.size > 0


def test_truncated_jpeg_fails(tmp_path):
    from PIL import Image
    p = tmp_path / "bad.jpg"
    Image.new("RGB", (32, 32), (200, 50, 50)).save(p, "JPEG")
    raw = p.read_bytes()
    p.write_bytes(raw[:-16])
    r = validate_file(p)
    assert r.ok is False
    assert r.format == "jpeg"
    assert "EOI" in r.reason


def test_missing_jpeg_soi_fails(tmp_path):
    p = tmp_path / "junk.jpg"
    p.write_bytes(b"\x00" * 64)
    r = validate_file(p)
    assert r.ok is False
    assert "SOI" in r.reason


def test_truncated_png_fails(tmp_path):
    from PIL import Image
    p = tmp_path / "bad.png"
    Image.new("RGB", (32, 32), (10, 10, 10)).save(p, "PNG")
    raw = p.read_bytes()
    p.write_bytes(raw[:-12])
    r = validate_file(p)
    assert r.ok is False
    assert r.format == "png"


def test_gif_signature_and_trailer(tmp_path):
    p = tmp_path / "bad.gif"
    p.write_bytes(b"GIF89a" + b"\x00" * 64)
    r = validate_file(p)
    assert r.ok is False
    assert r.format == "gif"


def test_unknown_extension_passes(tmp_path):
    p = tmp_path / "x.bin"
    p.write_bytes(b"\x00" * 64)
    r = validate_file(p)
    assert r.ok is True
    assert r.format is None


def test_missing_file_fails_cleanly(tmp_path):
    r = validate_file(tmp_path / "nope.jpg")
    assert r.ok is False
    assert "not found" in r.reason


def test_too_small_fails(tmp_path):
    p = tmp_path / "tiny.jpg"
    p.write_bytes(b"\xff\xd8\xff")
    r = validate_file(p)
    assert r.ok is False
    assert r.reason == "too small"
