import os
import re

import pytest

from app.services.errors import ValidationError
from app.services.uploads import store_upload

HEX_MP4 = re.compile(r"[0-9a-f]{32}\.mp4")


def upload(name, content=b"x"):
    return type("F", (), {"filename": name, "save": lambda self, path: open(path, "wb").write(content)})()


def test_store_upload_uses_server_name_and_confines_to_folder(tmp_path):
    stored = store_upload(upload("../../evil.mp4"), str(tmp_path), {".mp4", ".webm"})
    assert os.path.dirname(stored.path) == os.path.realpath(str(tmp_path))
    assert HEX_MP4.fullmatch(os.path.basename(stored.path))
    assert stored.original_name == "evil.mp4"
    assert os.path.isfile(stored.path)


def test_store_upload_rejects_disallowed_extension(tmp_path):
    with pytest.raises(ValidationError):
        store_upload(upload("clip.avi"), str(tmp_path), {".mp4", ".webm"})
    assert os.listdir(str(tmp_path)) == []


def test_store_upload_rejects_bad_names(tmp_path):
    for bad in (None, 42, ""):
        with pytest.raises(ValidationError):
            store_upload(type("F", (), {"filename": bad}), str(tmp_path))


def test_store_upload_enforces_size_cap(tmp_path):
    with pytest.raises(ValidationError):
        store_upload(upload("big.mp4", content=b"y" * 10), str(tmp_path), max_bytes=4)
    assert os.listdir(str(tmp_path)) == []
