"""Test malware detection callback"""

import pytest
from lasuite.malware_detection.enums import ReportStatus

from core import factories
from core.malware_detection import malware_detection_callback
from core.models import ItemTypeChoices, ItemUploadStateChoices

pytestmark = pytest.mark.django_db


def test_malware_detection_callback_safe(caplog):
    """Test malware detection callback for safe file"""
    item = factories.ItemFactory(
        update_upload_state=ItemUploadStateChoices.ANALYZING,
        type=ItemTypeChoices.FILE,
        filename="test.txt",
    )
    with caplog.at_level("INFO", logger="core.malware_detection"):
        malware_detection_callback(item.file_key, ReportStatus.SAFE, None, item_id=item.id)
        assert f"File {item.file_key} is safe" in caplog.text
    item.refresh_from_db()
    assert item.upload_state == ItemUploadStateChoices.READY


def test_malware_detection_callback_unsafe(caplog):
    """Test malware detection callback for unsafe file"""
    item = factories.ItemFactory(
        update_upload_state=ItemUploadStateChoices.ANALYZING,
        type=ItemTypeChoices.FILE,
        filename="test.txt",
    )
    with caplog.at_level("WARNING", logger="drive.security"):
        error_info = {"error": "test", "error_code": 4001}
        malware_detection_callback(
            item.file_key,
            ReportStatus.UNSAFE,
            error_info=error_info,
            item_id=item.id,
        )
        assert (
            f"File {item.file_key} for Item {item.id} is suspicious. Error info: {error_info}"
            in caplog.text
        )
        assert (
            f"File {item.file_key} for Item {item.id} has an unknown"
            f" reportstatus. Error info: {error_info}" not in caplog.text
        )

    item.refresh_from_db()
    assert item.upload_state == ItemUploadStateChoices.SUSPICIOUS
    assert item.malware_detection_info == {"error": "test", "error_code": 4001}


def test_malware_detection_callback_file_too_large(caplog):
    """Test malware detection callback for file too large"""
    item = factories.ItemFactory(
        update_upload_state=ItemUploadStateChoices.ANALYZING,
        type=ItemTypeChoices.FILE,
        filename="test.txt",
    )
    with caplog.at_level("INFO", logger="core.malware_detection"):
        error_info = {"error": "test", "error_code": 413}
        malware_detection_callback(
            item.file_key,
            ReportStatus.UNKNOWN,
            error_info=error_info,
            item_id=item.id,
        )
        assert (
            f"File {item.file_key} for Item {item.id} is suspicious. Error info: {error_info}"
            not in caplog.text
        )
        assert (
            f"File {item.file_key} for Item {item.id} has an unknown"
            f" reportstatus. Error info: {error_info}" in caplog.text
        )
    item.refresh_from_db()
    assert item.upload_state == ItemUploadStateChoices.FILE_TOO_LARGE_TO_ANALYZE


def test_malware_detection_callback_unknown_report_status(caplog):
    """Test malware detection callback for unknown report status.
    The file should be set to suspicious.
    """
    item = factories.ItemFactory(
        update_upload_state=ItemUploadStateChoices.ANALYZING,
        type=ItemTypeChoices.FILE,
        filename="test.txt",
    )
    with caplog.at_level("WARNING", logger="drive.security"):
        error_info = {}
        malware_detection_callback(
            item.file_key,
            ReportStatus.UNKNOWN,
            error_info=error_info,
            item_id=item.id,
        )
        assert (
            f"File {item.file_key} for Item {item.id} is suspicious. Error info: {error_info}"
            not in caplog.text
        )
        assert (
            f"File {item.file_key} for Item {item.id} has an unknown"
            f" reportstatus. Error info: {error_info}" in caplog.text
        )
    item.refresh_from_db()
    assert item.upload_state == ItemUploadStateChoices.SUSPICIOUS
    assert item.malware_detection_info == {}


def test_malware_detection_callback_item_does_not_exist(caplog):
    """Test malware detection callback for item that does not exist"""
    with caplog.at_level("INFO", logger="core.malware_detection"):
        malware_detection_callback(
            "test.txt",
            ReportStatus.UNKNOWN,
            error_info={},
            item_id=1,
        )
        assert "Item 1 does not exist anymore" in caplog.text
