"""#33 — download streams large files and still watermarks restricted PDFs."""

from __future__ import annotations

import itertools

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client
from django.urls import reverse

from apps.repository.documents.models import Document

PDF_BYTES = b"%PDF-1.4\n%\xe2\xe3\xcf\xd3\n1 0 obj<</Type/Catalog>>endobj\ntrailer<<>>\n%%EOF\n"
_seq = itertools.count(1)


def _doc(collection, owner, *, visibility, filename="paper.pdf", body=PDF_BYTES):
    return Document.objects.create(
        title="Maize yield under drought",
        abstract="Body.",
        collection=collection,
        document_type=Document.DocumentType.THESIS,
        license_type=Document.License.CC_BY,
        visibility=visibility,
        status=Document.Status.PUBLISHED,
        submitted_by=owner,
        public_document_id=f"DLS-{next(_seq):05d}",
        file=SimpleUploadedFile(filename, body, content_type="application/pdf"),
    )


def _bytes(resp):
    return b"".join(resp.streaming_content) if resp.streaming else resp.content


@pytest.mark.django_db
def test_open_access_download_streams_valid_pdf(public_collection, manager_user):
    doc = _doc(public_collection, manager_user, visibility=Document.Visibility.PUBLIC_OPEN)
    resp = Client().get(reverse("repo_documents:document_download", kwargs={"uid": doc.document_uid}))
    assert resp.status_code == 200
    # Streamed (not buffered into memory) for large-file safety.
    assert resp.streaming is True
    body = _bytes(resp)
    assert body == PDF_BYTES
    assert body.startswith(b"%PDF")
    assert resp["Content-Disposition"].startswith("attachment;")


@pytest.mark.django_db
def test_restricted_pdf_download_is_watermarked_and_readable(restricted_collection, manager_user):
    """The watermark branch buffers bytes in memory (not streamed) but must still
    deliver a valid PDF to a user authorised to download it."""
    doc = _doc(restricted_collection, manager_user, visibility=Document.Visibility.RESTRICTED)
    client = Client()
    client.force_login(manager_user)  # repo manager is an internal user → can download
    resp = client.get(reverse("repo_documents:document_download", kwargs={"uid": doc.document_uid}))
    assert resp.status_code == 200
    body = _bytes(resp)
    # Either watermarked-and-rewritten or passed through unchanged — both are PDFs.
    assert body.startswith(b"%PDF")
    assert resp["Content-Disposition"].startswith("attachment;")


@pytest.mark.django_db
def test_raw_endpoint_serves_inline(public_collection, manager_user):
    doc = _doc(public_collection, manager_user, visibility=Document.Visibility.PUBLIC_OPEN)
    resp = Client().get(reverse("repo_documents:document_raw", kwargs={"uid": doc.document_uid}))
    assert resp.status_code == 200
    assert _bytes(resp).startswith(b"%PDF")
    # Inline (so PDF.js / the browser renders it in place) rather than attachment.
    assert resp["Content-Disposition"].startswith("inline;")
