"""Upload validation is decided by bytes, never by names.

A file named photo.jpg that is really a script must be refused; a docx must be a real
docx, not any zip. These are the cases that make a client upload safe to store and serve.
"""

import io
import zipfile

from app.services.uploads import MAX_BYTES, safe_original_name, sniff, stored_name_for


def _docx() -> bytes:
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, "w") as zf:
        zf.writestr("[Content_Types].xml", "<Types/>")
        zf.writestr("word/document.xml", "<w:document/>")
    return buf.getvalue()


def _zip_not_docx() -> bytes:
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, "w") as zf:
        zf.writestr("evil.exe", b"MZ")
    return buf.getvalue()


class TestSniff:
    def test_jpeg_png_webp_gif(self):
        assert sniff(b"\xff\xd8\xff\xe0" + b"\0" * 20, "x.bin").content_type == "image/jpeg"
        assert sniff(b"\x89PNG\r\n\x1a\n" + b"\0" * 20, "x").content_type == "image/png"
        assert sniff(b"RIFF\0\0\0\0WEBPVP8 ", "x").content_type == "image/webp"
        assert sniff(b"GIF89a" + b"\0" * 10, "x").content_type == "image/gif"

    def test_pdf(self):
        assert sniff(b"%PDF-1.7\n%...", "article.pdf").kind == "document"

    def test_real_docx_accepted_other_zip_refused(self):
        assert sniff(_docx(), "article.docx").ext == "docx"
        assert sniff(_zip_not_docx(), "article.docx") is None

    def test_markdown_and_text(self):
        assert sniff("# Title\n\nBody".encode(), "piece.md").content_type == "text/markdown"
        assert sniff("plain words".encode(), "notes.txt").content_type == "text/plain"

    def test_binary_named_as_image_is_refused(self):
        # The name says jpg; the bytes are an ELF header. The name loses.
        assert sniff(b"\x7fELF\x02\x01\x01" + b"\0" * 20, "photo.jpg") is None

    def test_script_named_as_text_is_refused_when_not_utf8(self):
        assert sniff(b"\xff\xfe\x00\x01", "readme.txt") is None

    def test_empty_refused(self):
        assert sniff(b"", "x.md") is None


class TestNames:
    def test_original_name_is_never_a_path(self):
        assert safe_original_name("../../etc/passwd") == "passwd"
        assert safe_original_name("C:\\Users\\adam\\photo.jpg").endswith("photo.jpg")
        assert "/" not in safe_original_name("a/b/c.png")

    def test_original_name_bounded(self):
        assert len(safe_original_name("x" * 400 + ".jpg")) <= 255

    def test_stored_name_random_and_extensioned(self):
        a, b = stored_name_for("jpg"), stored_name_for("jpg")
        assert a != b and a.endswith(".jpg") and "/" not in a

    def test_cap_is_25mb(self):
        assert MAX_BYTES == 25 * 1024 * 1024
