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.workflows.set_network_info_on_ip_custom_field import (
    SetNetworkInfoOnIpCustomFieldActivities,
)


class TestGetIPCustomFieldDiff:
    async def test_get_diff_ticket_obj_none(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        mock_transaction_obj.ticket_obj = None
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == ([], {})

    async def test_get_diff_missing_ip_cf(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == ([], {})

    async def test_get_diff_no_ip_mapping(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct("", "", "", "Networks", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["IDK"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["1.1.1.1", "2.2.2.2"],
            {},
        )

    async def test_get_diff_empty_ip_mapping(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct("", "", "", "IP Mapping", []),
            structs.CustomFieldStruct("", "", "", "Networks", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["IDK"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["1.1.1.1", "2.2.2.2"],
            {},
        )

    async def test_get_diff_no_networks(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct("", "", "", "IP Mapping", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["IDK"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["1.1.1.1", "2.2.2.2"],
            {},
        )

    async def test_get_diff_empty_networks(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct("", "", "", "IP Mapping", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Networks", []),
            structs.CustomFieldStruct("", "", "", "Departments", ["IDK"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["1.1.1.1", "2.2.2.2"],
            {},
        )

    async def test_get_diff_no_departments(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct("", "", "", "IP Mapping", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Networks", ["IDK"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["1.1.1.1", "2.2.2.2"],
            {},
        )

    async def test_get_diff_empty_departments(
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct("", "", "", "IP Mapping", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Networks", ["IDK"]),
            structs.CustomFieldStruct("", "", "", "Departments", []),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["1.1.1.1", "2.2.2.2"],
            {},
        )

    async def test_get_diff_ip_already_in_mapping(  # FIX MANUALLY ADDED IP MAPPING
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct(
                "",
                "",
                "",
                "IP Mapping",
                ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP", "2.2.2.2,\tNetwork: NET,\tDepartment: DEP"],
            ),
            structs.CustomFieldStruct("", "", "", "Networks", ["NET"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["DEP"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            [],
            {},
        )

    async def test_get_diff_new_ip_missing_old_network_and_department(  # FIX MANUALLY REMOVED NETWORK, DEPARTMENT
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2", "3.3.3.3"]),
            structs.CustomFieldStruct(
                "",
                "",
                "",
                "IP Mapping",
                ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP", "IP: 2.2.2.2,\tNetwork: NET2,\tDepartment: DEP2"],
            ),
            structs.CustomFieldStruct("", "", "", "Networks", ["NET"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["DEP"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["3.3.3.3"],
            {
                "Departments": ["DEP", "DEP2"],
                "Networks": ["NET", "NET2"],
            },
        )

    async def test_get_diff_ip_address_added(  # VALID STATE
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1", "2.2.2.2"]),
            structs.CustomFieldStruct(
                "",
                "",
                "",
                "IP Mapping",
                ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP"],
            ),
            structs.CustomFieldStruct("", "", "", "Networks", ["NET"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["DEP"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            ["2.2.2.2"],
            {},
        )

    async def test_get_diff_ip_address_removed(  # VALID STATE
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1"]),
            structs.CustomFieldStruct(
                "",
                "",
                "",
                "IP Mapping",
                ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP", "IP: 2.2.2.2,\tNetwork: NET2,\tDepartment: DEP2"],
            ),
            structs.CustomFieldStruct("", "", "", "Networks", ["NET", "NET2"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["DEP", "DEP2"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            [],
            {
                "IP Mapping": ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP"],
                "Departments": ["DEP"],
                "Networks": ["NET"],
            },
        )

    async def test_get_diff_ip_address_removed_network_subnet_should_stay(  # VALID STATE
        self,
        test_activity_env: ActivityEnvironment,
        worker_config: WorkerConfig,
        mock_transaction_obj: structs.TransactionStruct,
    ) -> None:
        activities = SetNetworkInfoOnIpCustomFieldActivities(worker_config.rt.ignored_users)
        assert mock_transaction_obj.ticket_obj is not None
        mock_transaction_obj.ticket_obj.custom_fields = [
            structs.CustomFieldStruct("", "", "", "IP", ["1.1.1.1"]),
            structs.CustomFieldStruct(
                "",
                "",
                "",
                "IP Mapping",
                ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP", "IP: 2.2.2.2,\tNetwork: NET,\tDepartment: DEP"],
            ),
            structs.CustomFieldStruct("", "", "", "Networks", ["NET"]),
            structs.CustomFieldStruct("", "", "", "Departments", ["DEP"]),
        ]
        assert (await test_activity_env.run(activities.get_ip_custom_field_diff, mock_transaction_obj)) == (
            [],
            {
                "IP Mapping": ["IP: 1.1.1.1,\tNetwork: NET,\tDepartment: DEP"],
            },
        )
