import io
import time
import requests
from PIL import Image
from tests.conftest import BASE_URL


def _session():
    s = requests.Session()
    name = f"up_{int(time.time() * 1000)}"
    s.post(f"{BASE_URL}/auth/signup", data={
        "username": name,
        "email": f"{name}@test.dev",
        "password": "secret123",
        "confirm_password": "secret123",
    }, allow_redirects=True)
    return s


def _png_bytes():
    buf = io.BytesIO()
    Image.new("RGB", (4, 4), (255, 0, 0)).save(buf, "PNG")
    return buf.getvalue()


def test_upload_allowed_png(app_server):
    s = _session()
    r = s.post(f"{BASE_URL}/uploads/upload", files={"file": ("x.png", _png_bytes(), "image/png")})
    assert r.status_code == 201, r.text
    assert "url" in r.json()


def test_upload_rejects_svg(app_server):
    s = _session()
    r = s.post(f"{BASE_URL}/uploads/upload", files={"file": ("x.svg", b"<svg/>", "image/svg+xml")})
    assert r.status_code == 415


def test_upload_rejects_html(app_server):
    s = _session()
    r = s.post(f"{BASE_URL}/uploads/upload", files={"file": ("x.html", b"<html></html>", "text/html")})
    assert r.status_code == 415


def test_upload_rejects_oversize(app_server):
    s = _session()
    big = b"\x89PNG\r\n" + b"\x00" * (11 * 1024 * 1024)
    r = s.post(f"{BASE_URL}/uploads/upload", files={"file": ("big.png", big, "image/png")})
    assert r.status_code == 413


def test_uploaded_file_served_as_attachment(app_server):
    s = _session()
    r = s.post(f"{BASE_URL}/uploads/upload", files={"file": ("x.png", _png_bytes(), "image/png")})
    url = r.json()["url"]
    served = s.get(f"{BASE_URL}{url}")
    assert served.status_code == 200
    assert served.headers.get("Content-Disposition") == "attachment"


def test_upload_requires_login(app_server):
    r = requests.post(f"{BASE_URL}/uploads/upload", files={"file": ("x.png", _png_bytes(), "image/png")}, allow_redirects=False)
    assert r.status_code in (302, 303)


def test_delete_own_allowed_other_user_forbidden(app_server):
    alice = _session()
    uid = alice.post(f"{BASE_URL}/uploads/upload", files={"file": ("x.png", _png_bytes(), "image/png")}).json()["uid"]
    bob = _session()
    assert bob.delete(f"{BASE_URL}/uploads/delete/{uid}").status_code == 403
    assert alice.delete(f"{BASE_URL}/uploads/delete/{uid}").status_code == 200
