import pytest
import pytest_mock
from temporalio.testing import ActivityEnvironment

from csirtmu.beta_temporal.config import Config as WorkerConfig
from csirtmu.beta_temporal.external_services.alpha.client import AlphaClient
from csirtmu.beta_temporal.external_services.rt import structs
from csirtmu.beta_temporal.external_services.rt.client import RTClient
from csirtmu.beta_temporal.workflows.handle_copyright_infringement import CopyrightHandlingActivities


class TestIsCopyrightNotice:
    async def test_is_copyright_notice_ticket_data_none(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = None

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert not await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_copyright_notice_created_by_devel(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.transaction.creator.id = "devel"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert not await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_copyright_notice_csirt_sender(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("From", "csirt@muni.cz")
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert not await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_copyright_notice_no_copyright_mention(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert not await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    @pytest.mark.parametrize("sender", ["copyright", "IDK"])
    async def test_is_copyright_notice_copyright_in_sender_no_xml(
        self,
        sender: str,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("From", sender)
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert not await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    @pytest.mark.parametrize("subject", ["copyright", "infringement", "IDK"])
    async def test_is_copyright_notice_copyright_in_subject_no_xml(
        self,
        subject: str,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("Subject", subject)
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert not await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_copyright_notice_copyright_in_sender_xml_in_body(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("From", "copyright")
        mock_ticket_data.body = "Start ACNS XML"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    @pytest.mark.parametrize("subject", ["copyright", "infringement"])
    async def test_is_copyright_notice_copyright_in_subject_xml_in_body(
        self,
        subject: str,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("Subject", subject)
        mock_ticket_data.body = "Start ACNS XML"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_copyright_notice_copyright_in_sender_xml_in_attachment_content_type(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("From", "copyright")
        mock_ticket_data.attachments[0].content_type = "idk/xml"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    @pytest.mark.parametrize("subject", ["copyright", "infringement"])
    async def test_is_copyright_notice_copyright_in_subject_xml_in_attachment_content_type(
        self,
        subject: str,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("Subject", subject)
        mock_ticket_data.attachments[0].content_type = "idk/xml"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_copyright_notice_copyright_in_sender_xml_in_attachment_filename(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("From", "copyright")
        mock_ticket_data.attachments[0].filename = "xdddds.xml"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    @pytest.mark.parametrize("subject", ["copyright", "infringement"])
    async def test_is_copyright_notice_copyright_in_subject_xml_in_attachment_filename(
        self,
        subject: str,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        mock_ticket_data.headers.add_header("Subject", subject)
        mock_ticket_data.attachments[0].filename = "xdddd.xml"
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.handle_copyright_infringement.RTClient.get_ticket_data",
        )
        get_ticket_data_mock.return_value = mock_ticket_data

        activities = CopyrightHandlingActivities("", RTClient(worker_config.rt), AlphaClient(worker_config.alpha))
        assert await test_activity_env.run(activities.is_copyright_notice, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)
