"""Slice A · A8 — FileSafetyValidator unit tests.

The validators are the foundation for safe pitch deck, deal-room document,
and signed-MoU uploads. These tests live with the validator itself so the
contract is locked at the module boundary.
"""
from __future__ import annotations

from io import BytesIO

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

from apps.smehub._shared.validators import (
    DEAL_ROOM_ATTACHMENT_VALIDATOR,
    PITCH_DECK_VALIDATOR,
    SIGNED_AGREEMENT_VALIDATOR,
    FileSafetyValidator,
)


def _file(name: str, *, size: int = 1024, content_type: str = "application/pdf"):
    return SimpleUploadedFile(name, b"x" * size, content_type=content_type)


class TestPitchDeckValidator:
    def test_pdf_passes(self):
        PITCH_DECK_VALIDATOR(_file("deck.pdf"))

    def test_pptx_passes(self):
        PITCH_DECK_VALIDATOR(_file("deck.pptx", content_type="application/vnd.openxmlformats-officedocument.presentationml.presentation"))

    def test_exe_rejected(self):
        with pytest.raises(ValidationError) as exc:
            PITCH_DECK_VALIDATOR(_file("malware.exe", content_type="application/octet-stream"))
        assert exc.value.code == "unsupported_extension"

    def test_oversize_rejected(self):
        big = SimpleUploadedFile("deck.pdf", b"x" * (26 * 1024 * 1024), content_type="application/pdf")
        with pytest.raises(ValidationError) as exc:
            PITCH_DECK_VALIDATOR(big)
        assert exc.value.code == "file_too_large"

    def test_none_passes(self):
        PITCH_DECK_VALIDATOR(None)


class TestSignedAgreementValidator:
    def test_pdf_passes(self):
        SIGNED_AGREEMENT_VALIDATOR(_file("agreement.pdf"))

    def test_docx_rejected(self):
        with pytest.raises(ValidationError):
            SIGNED_AGREEMENT_VALIDATOR(_file(
                "agreement.docx",
                content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            ))

    def test_bogus_content_type_rejected(self):
        with pytest.raises(ValidationError) as exc:
            SIGNED_AGREEMENT_VALIDATOR(_file("agreement.pdf", content_type="text/html"))
        assert exc.value.code == "unsupported_content_type"


class TestDealRoomAttachmentValidator:
    def test_png_passes(self):
        DEAL_ROOM_ATTACHMENT_VALIDATOR(_file("chart.png", content_type="image/png"))

    def test_script_rejected(self):
        with pytest.raises(ValidationError):
            DEAL_ROOM_ATTACHMENT_VALIDATOR(_file("evil.js", content_type="text/javascript"))


class TestFactoryReuse:
    """Confirm the deconstructible factory accepts custom extension lists
    and the deconstruct equality holds — required for migrations later."""

    def test_custom_extension(self):
        v = FileSafetyValidator(allowed_extensions=("txt",), max_size_mb=1)
        v(_file("notes.txt", content_type="text/plain"))
        with pytest.raises(ValidationError):
            v(_file("notes.pdf", content_type="application/pdf"))

    def test_equality(self):
        a = FileSafetyValidator(allowed_extensions=("pdf",), max_size_mb=10)
        b = FileSafetyValidator(allowed_extensions=("pdf",), max_size_mb=10)
        assert a == b
