import base64

import pytest_mock
from temporalio.testing import ActivityEnvironment

from csirtmu.beta_temporal.config import Config as WorkerConfig
from csirtmu.beta_temporal.external_services.rt import structs
from csirtmu.beta_temporal.external_services.rt.client import RTClient
from csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment import (
    MattermostNotificationOnAnalyticsCommentActivities,
)


class TestIsAnalyticsComment:
    async def test_is_analytics_comment_not_category_analytics(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        test_activity_env: ActivityEnvironment,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = []
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        assert not await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)

    async def test_is_analytics_comment_ticket_data_is_none(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        get_ticket_data_mock.return_value = None
        assert not await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_analytics_comment_mention_in_body(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        mock_ticket_data.body = "[@analytics]"
        get_ticket_data_mock.return_value = mock_ticket_data
        assert await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_analytics_comment_mention_in_body_quoted(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        mock_ticket_data.body = "<blockquote>\n[@analytics]\n</blockquote>"
        get_ticket_data_mock.return_value = mock_ticket_data
        assert not await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_analytics_comment_mention_in_attachment(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        mock_ticket_data.attachments[0].content_type = "text/plain"
        mock_ticket_data.attachments[0].content = "[@analytics]"
        get_ticket_data_mock.return_value = mock_ticket_data
        assert await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_analytics_comment_mention_in_attachment_quoted(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        mock_ticket_data.attachments[0].content_type = "text/plain"
        mock_ticket_data.attachments[0].content = "<blockquote>\n[@analytics]\n</blockquote>"
        get_ticket_data_mock.return_value = mock_ticket_data
        assert not await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_analytics_comment_mention_in_attachment_base64(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        mock_ticket_data.attachments[0].content_type = "text/plain"
        mock_ticket_data.attachments[0].content = base64.b64encode(b"[@analytics]").decode()
        get_ticket_data_mock.return_value = mock_ticket_data
        assert await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)

    async def test_is_analytics_comment_mention_in_attachment_quoted_base64(
        self,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
        mock_ticket_data: structs.TicketData,
        test_activity_env: ActivityEnvironment,
        mocker: pytest_mock.MockerFixture,
    ) -> None:
        assert mock_transaction_obj.ticket_obj is not None
        activities = MattermostNotificationOnAnalyticsCommentActivities(RTClient(worker_config.rt))
        get_ticket_data_mock = mocker.patch(
            "csirtmu.beta_temporal.workflows.mattermost_notification_on_analytics_comment.RTClient.get_ticket_data",
        )
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct(id="", url="", type="", name="Category", _values=["Analytics"]),
        ]
        mock_ticket_data.attachments[0].content_type = "text/plain"
        mock_ticket_data.attachments[0].content = base64.b64encode(
            b"<blockquote>\n[@analytics]\n</blockquote>"
        ).decode()
        get_ticket_data_mock.return_value = mock_ticket_data
        assert not await test_activity_env.run(activities.is_analytics_comment, mock_transaction_obj)
        get_ticket_data_mock.assert_called_once_with(mock_transaction_obj)
