"""PRD §5.1 FRFA-AM006 — uploaded files are scanned and infected files rejected.

End-to-end: the application document upload path calls validate_grant_upload,
which routes through ClamAV's scan_stream_optional. When clamd reports a
FOUND signature, ValidationError must propagate up to the caller.

The test uses the canonical EICAR string (the safe test-pattern every
AV engine flags) so the assertion documents what infected content looks
like. Because the test container may not run clamd, we patch
``scan_stream_optional`` to behave the way clamd would when it sees EICAR —
i.e. raise ValidationError — and assert the pipeline propagates correctly.
"""

from __future__ import annotations

import io
from unittest.mock import patch

import pytest
from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile

from apps.rims.grants.services import validate_grant_upload

EICAR_STRING = (
    b"X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"
)


def _eicar_upload(name: str = "infected.txt") -> SimpleUploadedFile:
    return SimpleUploadedFile(name, EICAR_STRING, content_type="text/plain")


@pytest.mark.django_db
def test_eicar_upload_is_rejected_by_pipeline(settings):
    """FRFA-AM006 — the upload pipeline rejects content that the scanner flags.

    Settings are nudged so the ``CLAMD_TCP_HOST`` gate in the validator is
    open; the actual TCP call is mocked because no clamd is running in CI.
    """
    settings.CLAMD_TCP_HOST = "clamd-mock"
    settings.CLAMD_TCP_PORT = 3310
    settings.CLAMD_ENABLED = True

    def _flag_eicar(stream):
        try:
            data = stream.read()
            stream.seek(0)
        except Exception:
            data = b""
        if EICAR_STRING in data:
            raise ValidationError("Uploaded file failed virus scan.")

    # The PDF-style header is needed because the validator runs magic-byte
    # checks before reaching the scanner. We mark the body as a fake PDF and
    # smuggle the EICAR signature after the header for the AV to discover.
    body = b"%PDF-1.4\n" + EICAR_STRING + b"\n%%EOF\n"
    upload = SimpleUploadedFile("invoice.pdf", body, content_type="application/pdf")
    with patch(
        "apps.core.storage.validators.scan_stream_optional", side_effect=_flag_eicar
    ):
        with pytest.raises(ValidationError) as excinfo:
            validate_grant_upload(upload, call=None)
    assert "virus" in str(excinfo.value).lower()


@pytest.mark.django_db
def test_benign_pdf_upload_is_accepted(settings):
    """FRFA-AM006 — non-infected uploads pass through cleanly."""
    settings.CLAMD_TCP_HOST = "clamd-mock"
    settings.CLAMD_ENABLED = True

    body = b"%PDF-1.4\nbenign content\n%%EOF\n"
    benign = SimpleUploadedFile(
        "proposal.pdf", body, content_type="application/pdf"
    )
    with patch("apps.core.storage.validators.scan_stream_optional", return_value=None):
        validate_grant_upload(benign, call=None)


@pytest.mark.django_db
def test_eicar_string_is_present_for_documentation():
    """Document the canonical EICAR test pattern so future readers can verify."""
    assert len(EICAR_STRING) == 68
    assert EICAR_STRING.startswith(b"X5O!P%@AP")
    assert b"EICAR-STANDARD-ANTIVIRUS-TEST-FILE" in EICAR_STRING
    # Sanity: the test fixture wraps it as an InMemoryUploadedFile correctly.
    upload = _eicar_upload()
    body = upload.read()
    assert body == EICAR_STRING
