"""Unit tests for UniFi to ServiceNow transformation functions."""

from beast_dream_snow_loader.models.servicenow import (
    ServiceNowEndpoint,
    ServiceNowGatewayCI,
    ServiceNowLocation,
    ServiceNowNetworkDeviceCI,
)
from beast_dream_snow_loader.models.unifi import (
    UniFiClient,
    UniFiDevice,
    UniFiHost,
    UniFiSite,
)
from beast_dream_snow_loader.transformers.unifi_to_snow import (
    transform_client,
    transform_device,
    transform_host,
    transform_site,
)


class TestTransformHost:
    """Test transform_host function."""

    def test_transform_host_with_minimal_data(self):
        """Test transforming minimal UniFi host to ServiceNow gateway CI."""
        unifi_host = UniFiHost(
            id="test-host-id",
            hardwareId="UDM-Pro",
            type="gateway",
            ipAddress="192.168.1.1",
            owner=True,
            isBlocked=False,
            registrationTime="1700000000",
            lastConnectionStateChange="1700000000",
            latestBackupTime="1700000000",
            reportedState={
                "controller_uuid": "uuid-123",
                "host_type": 1,
                "hostname": "udm-pro",
                "mgmt_port": 8080,
                "name": "UDM-Pro",
                "state": "CONNECTED",
                "version": "1.12.33",
            },
            userData={"status": "ACTIVE"},
        )

        result = transform_host(unifi_host)

        assert isinstance(result, ServiceNowGatewayCI)
        assert result.u_unifi_source_id == "test-host-id"
        assert result.sys_id is None  # sys_id auto-generated by ServiceNow
        assert result.hostname == "udm-pro"
        assert result.ip_address == "192.168.1.1"
        assert result.name == "UDM-Pro"
        assert result.firmware_version == "1.12.33"
        assert result.state == "CONNECTED"

    def test_transform_host_flattens_nested_fields(self):
        """Test that nested fields are properly flattened."""
        unifi_host = UniFiHost(
            id="test-host-id",
            hardwareId="UDM-Pro",
            type="gateway",
            ipAddress="192.168.1.1",
            owner=True,
            isBlocked=False,
            registrationTime="1700000000",
            lastConnectionStateChange="1700000000",
            latestBackupTime="1700000000",
            reportedState={
                "controller_uuid": "uuid-123",
                "host_type": 1,
                "hostname": "udm-pro",
                "mgmt_port": 8080,
                "name": "UDM-Pro",
                "state": "CONNECTED",
                "version": "1.12.33",
                "hardware": {"mac": "00:11:22:33:44:55", "serialno": "ABC123"},
            },
            userData={"status": "ACTIVE"},
        )

        result = transform_host(unifi_host)

        assert result.mac_address == "00:11:22:33:44:55"
        assert result.serial_number == "ABC123"

    def test_transform_host_handles_missing_fields(self):
        """Test that missing optional fields are handled gracefully."""
        unifi_host = UniFiHost(
            id="test-host-id",
            hardwareId="UDM-Pro",
            type="gateway",
            ipAddress="192.168.1.1",
            owner=True,
            isBlocked=False,
            registrationTime="1700000000",
            lastConnectionStateChange="1700000000",
            latestBackupTime="1700000000",
            reportedState={
                "controller_uuid": "uuid-123",
                "host_type": 1,
                "hostname": "udm-pro",
                "mgmt_port": 8080,
                "name": "UDM-Pro",
                "state": "CONNECTED",
                "version": "1.12.33",
            },
            userData={"status": "ACTIVE"},
        )

        result = transform_host(unifi_host)

        # Should not raise error, optional fields should be None
        assert result.mac_address is None or isinstance(result.mac_address, str)

    def test_transform_host_validates_output(self):
        """Test that output validates against ServiceNow model."""
        unifi_host = UniFiHost(
            id="test-host-id",
            hardwareId="UDM-Pro",
            type="gateway",
            ipAddress="192.168.1.1",
            owner=True,
            isBlocked=False,
            registrationTime="1700000000",
            lastConnectionStateChange="1700000000",
            latestBackupTime="1700000000",
            reportedState={
                "controller_uuid": "uuid-123",
                "host_type": 1,
                "hostname": "udm-pro",
                "mgmt_port": 8080,
                "name": "UDM-Pro",
                "state": "CONNECTED",
                "version": "1.12.33",
            },
            userData={"status": "ACTIVE"},
        )

        result = transform_host(unifi_host)

        # Should be valid ServiceNowGatewayCI instance
        assert isinstance(result, ServiceNowGatewayCI)
        # Should have required fields
        assert result.u_unifi_source_id is not None
        assert result.name is not None
        assert result.ip_address is not None
        assert result.hostname is not None


class TestTransformSite:
    """Test transform_site function."""

    def test_transform_site_with_minimal_data(self):
        """Test transforming minimal UniFi site to ServiceNow location."""
        unifi_site = UniFiSite(
            siteId="test-site-id",
            hostId="test-host-id",
            permission="read",
            isOwner=True,
            meta={
                "desc": "Test site description",
                "name": "Test Site",
                "timezone": "America/New_York",
            },
            statistics={
                "counts": {
                    "criticalNotification": 0,
                    "gatewayDevice": 1,
                    "guestClient": 0,
                    "lanConfiguration": 0,
                    "offlineDevice": 0,
                    "offlineGatewayDevice": 0,
                    "offlineWifiDevice": 0,
                    "offlineWiredDevice": 0,
                    "pendingUpdateDevice": 0,
                    "totalDevice": 5,
                    "wanConfiguration": 1,
                    "wifiClient": 10,
                    "wifiConfiguration": 1,
                    "wifiDevice": 3,
                    "wiredClient": 2,
                    "wiredDevice": 2,
                },
            },
        )

        result = transform_site(unifi_site)

        assert isinstance(result, ServiceNowLocation)
        assert result.u_unifi_source_id == "test-site-id"
        assert result.sys_id is None  # sys_id auto-generated by ServiceNow
        assert result.name == "Test Site"
        assert result.description == "Test site description"
        assert result.timezone == "America/New_York"
        # Note: host_id relationship handled in Phase 2 (two-phase linking)
        # During transformation, host_id is None (will be set in linking phase)

    def test_transform_site_preserves_relationships(self):
        """Test that site-to-host relationships are preserved.

        Note: Relationships are handled in Phase 2 (two-phase linking).
        During transformation, relationships are NOT set (they require sys_id references).
        """
        unifi_site = UniFiSite(
            siteId="test-site-id",
            hostId="test-host-id",
            permission="read",
            isOwner=True,
            meta={
                "desc": "Test site description",
                "name": "Test Site",
                "timezone": "America/New_York",
            },
            statistics={
                "counts": {
                    "criticalNotification": 0,
                    "gatewayDevice": 1,
                    "guestClient": 0,
                    "lanConfiguration": 0,
                    "offlineDevice": 0,
                    "offlineGatewayDevice": 0,
                    "offlineWifiDevice": 0,
                    "offlineWiredDevice": 0,
                    "pendingUpdateDevice": 0,
                    "totalDevice": 5,
                    "wanConfiguration": 1,
                    "wifiClient": 10,
                    "wifiConfiguration": 1,
                    "wifiDevice": 3,
                    "wiredClient": 2,
                    "wiredDevice": 2,
                },
            },
        )

        result = transform_site(unifi_site)

        # Relationships handled in Phase 2 (after records created and sys_ids captured)
        # During transformation, host_id is None (will be set in linking phase)
        assert result.host_id is None

    def test_transform_site_validates_output(self):
        """Test that output validates against ServiceNow model."""
        unifi_site = UniFiSite(
            siteId="test-site-id",
            hostId="test-host-id",
            permission="read",
            isOwner=True,
            meta={
                "desc": "Test site description",
                "name": "Test Site",
                "timezone": "America/New_York",
            },
            statistics={
                "counts": {
                    "criticalNotification": 0,
                    "gatewayDevice": 1,
                    "guestClient": 0,
                    "lanConfiguration": 0,
                    "offlineDevice": 0,
                    "offlineGatewayDevice": 0,
                    "offlineWifiDevice": 0,
                    "offlineWiredDevice": 0,
                    "pendingUpdateDevice": 0,
                    "totalDevice": 5,
                    "wanConfiguration": 1,
                    "wifiClient": 10,
                    "wifiConfiguration": 1,
                    "wifiDevice": 3,
                    "wiredClient": 2,
                    "wiredDevice": 2,
                },
            },
        )

        result = transform_site(unifi_site)

        assert isinstance(result, ServiceNowLocation)
        assert result.u_unifi_source_id is not None
        assert result.name is not None
        assert result.description is not None
        assert result.timezone is not None


class TestTransformDevice:
    """Test transform_device function."""

    def test_transform_device_with_minimal_data(self):
        """Test transforming minimal UniFi device to ServiceNow network device CI."""
        unifi_device = UniFiDevice(
            hostId="test-device-id",
            updatedAt="2025-01-01T00:00:00Z",
        )

        result = transform_device(unifi_device)

        assert isinstance(result, ServiceNowNetworkDeviceCI)
        assert result.u_unifi_source_id == "test-device-id"
        assert result.sys_id is None  # sys_id auto-generated by ServiceNow
        assert result.name is not None

    def test_transform_device_extracts_identifiers(self):
        """Test that device identifiers are correctly extracted."""
        unifi_device = UniFiDevice(
            hostId="test-device-id",
            updatedAt="2025-01-01T00:00:00Z",
            mac="00:11:22:33:44:55",
            serial="ABC123",
            model="USW-Pro-48",
        )

        result = transform_device(unifi_device)

        assert result.mac_address == "00:11:22:33:44:55"
        assert result.serial_number == "ABC123"
        assert result.model == "USW-Pro-48"

    def test_transform_device_validates_output(self):
        """Test that output validates against ServiceNow model."""
        unifi_device = UniFiDevice(
            hostId="test-device-id",
            updatedAt="2025-01-01T00:00:00Z",
            mac="00:11:22:33:44:55",
        )

        result = transform_device(unifi_device)

        assert isinstance(result, ServiceNowNetworkDeviceCI)
        assert result.u_unifi_source_id is not None
        assert result.name is not None
        assert result.mac_address is not None


class TestTransformClient:
    """Test transform_client function."""

    def test_transform_client_with_minimal_data(self):
        """Test transforming minimal UniFi client to ServiceNow endpoint."""
        unifi_client = UniFiClient(
            hostname="test-client",
            ip="192.168.1.100",
            mac="00:11:22:33:44:55",
        )

        result = transform_client(unifi_client)

        assert isinstance(result, ServiceNowEndpoint)
        assert result.hostname == "test-client"
        assert result.ip_address == "192.168.1.100"
        assert result.mac_address == "00:11:22:33:44:55"

    def test_transform_client_identifies_device_type(self):
        """Test that device types are correctly identified."""
        unifi_client = UniFiClient(
            hostname="test-phone",
            ip="192.168.1.101",
            mac="00:11:22:33:44:56",
            deviceType="phone",
        )

        result = transform_client(unifi_client)

        assert result.device_type == "phone"

    def test_transform_client_preserves_relationships(self):
        """Test that client-to-site/device relationships are preserved.

        Note: Relationships are handled in Phase 2 (two-phase linking).
        During transformation, relationships are NOT set (they require sys_id references).
        """
        unifi_client = UniFiClient(
            hostname="test-client",
            ip="192.168.1.100",
            mac="00:11:22:33:44:55",
            siteId="test-site-id",
            deviceId="test-device-id",
        )

        result = transform_client(unifi_client)

        # Relationships handled in Phase 2 (after records created and sys_ids captured)
        # During transformation, relationships are None (will be set in linking phase)
        assert result.site_id is None
        assert result.device_id is None

    def test_transform_client_validates_output(self):
        """Test that output validates against ServiceNow model."""
        unifi_client = UniFiClient(
            hostname="test-client",
            ip="192.168.1.100",
            mac="00:11:22:33:44:55",
        )

        result = transform_client(unifi_client)

        assert isinstance(result, ServiceNowEndpoint)
        assert result.u_unifi_source_id is not None
        assert result.hostname is not None
        assert result.ip_address is not None
        assert result.mac_address is not None
