"""Tests for the malware detection admin class."""

from django.contrib import admin
from django.test import RequestFactory

import pytest
from lasuite.malware_detection.models import MalwareDetection, MalwareDetectionStatus

from core import factories, models
from core.admin import MalwareDetectionAdmin

pytestmark = pytest.mark.django_db


def _create_detections():
    """Create one detection related to an existing item and one orphan detection."""
    item = factories.ItemFactory(type=models.ItemTypeChoices.FILE, filename="foo.txt", size=1234)
    detection = MalwareDetection.objects.create(
        path=item.file_key,
        status=MalwareDetectionStatus.PROCESSING,
        parameters={"item_id": str(item.id)},
    )
    orphan = MalwareDetection.objects.create(
        path="item/00000000-0000-0000-0000-000000000000/file.bin",
        status=MalwareDetectionStatus.PROCESSING,
        parameters={"item_id": "00000000-0000-0000-0000-000000000000"},
    )
    return detection, orphan


def _changelist_queryset(admin_instance, params):
    """Return the changelist queryset for the given GET parameters."""
    request = RequestFactory().get("/", params)
    request.user = factories.UserFactory(is_staff=True, is_superuser=True)
    changelist = admin_instance.get_changelist_instance(request)
    return changelist.get_queryset(request)


def test_admin_malware_detection_annotates_item_existence():
    """The admin queryset annotates each record with the existence of its item."""
    detection, orphan = _create_detections()

    queryset = MalwareDetectionAdmin(MalwareDetection, admin.site).get_queryset(None)

    assert queryset.get(pk=detection.pk).item_exists is True
    assert queryset.get(pk=orphan.pk).item_exists is False


def test_admin_malware_detection_annotates_item_size():
    """The admin queryset annotates each record with the size of its item."""
    detection, orphan = _create_detections()

    queryset = MalwareDetectionAdmin(MalwareDetection, admin.site).get_queryset(None)

    assert queryset.get(pk=detection.pk).item_size == 1234
    assert queryset.get(pk=orphan.pk).item_size is None


def test_admin_malware_detection_item_exists_filter():
    """The item exists filter splits records on the existence of their item."""
    detection, orphan = _create_detections()
    admin_instance = MalwareDetectionAdmin(MalwareDetection, admin.site)

    assert list(_changelist_queryset(admin_instance, {"item_exists": "yes"})) == [detection]
    assert list(_changelist_queryset(admin_instance, {"item_exists": "no"})) == [orphan]
    assert set(_changelist_queryset(admin_instance, {})) == {detection, orphan}
