"""Tests for drift event normalizer."""

from __future__ import annotations

import pytest
from backend.drift.event_normalizer import (
    normalize_event,
)

# ---------------------------------------------------------------------------
# Fixture event payloads
# ---------------------------------------------------------------------------

_GCP_INSTANCE_NAME = (
    "//compute.googleapis.com/projects/my-proj/zones/us-central1-a/instances/vm1"
)

GCP_CAI_CREATE_EVENT = {
    "asset": {
        "name": _GCP_INSTANCE_NAME,
        "assetType": "compute.googleapis.com/Instance",
        "resource": {"data": {}},
    },
    "priorAsset": None,
    "window": {"startTime": "2026-01-01T00:00:00Z"},
}

GCP_CAI_UPDATE_EVENT = {
    "asset": {
        "name": _GCP_INSTANCE_NAME,
        "assetType": "compute.googleapis.com/Instance",
        "resource": {"data": {}},
    },
    "priorAsset": {"resource": {"data": {}}},
    "window": {"startTime": "2026-01-01T00:00:00Z"},
}

GCP_CAI_DELETE_EVENT = {
    "asset": None,
    "priorAsset": {
        "name": _GCP_INSTANCE_NAME,
        "assetType": "compute.googleapis.com/Instance",
        "resource": {"data": {}},
    },
    "window": {"startTime": "2026-01-01T00:00:00Z"},
}

AWS_CONFIG_CREATE_EVENT = {
    "source": "aws.config",
    "detail-type": "Config Configuration Item Change",
    "detail": {
        "configurationItem": {
            "resourceType": "AWS::EC2::Instance",
            "resourceId": "i-1234567890abcdef0",
            "awsAccountId": "123456789012",
            "configurationItemCaptureTime": "2026-01-01T00:00:00Z",
        },
        "configurationItemDiff": {"changeType": "CREATE"},
    },
}

AWS_CONFIG_DELETE_EVENT = {
    "source": "aws.config",
    "detail-type": "Config Configuration Item Change",
    "detail": {
        "configurationItem": {
            "resourceType": "AWS::EC2::Instance",
            "resourceId": "i-1234567890abcdef0",
            "awsAccountId": "123456789012",
            "configurationItemCaptureTime": "2026-01-01T00:00:00Z",
        },
        "configurationItemDiff": {"changeType": "DELETE"},
    },
}

_AZURE_VM_URI = (
    "/subscriptions/sub-123/resourceGroups/rg"
    "/providers/Microsoft.Compute/virtualMachines/vm1"
)
_AZURE_SA_URI = (
    "/subscriptions/sub-456/resourceGroups/rg"
    "/providers/Microsoft.Storage/storageAccounts/sa1"
)

AZURE_WRITE_EVENT = {
    "eventType": "Microsoft.Resources.ResourceWriteSuccess",
    "data": {
        "resourceUri": _AZURE_VM_URI,
        "operationName": ("Microsoft.Compute/virtualMachines/write"),
        "status": "Succeeded",
    },
    "eventTime": "2026-01-01T00:00:00Z",
}

AZURE_DELETE_EVENT = {
    "eventType": "Microsoft.Resources.ResourceDeleteSuccess",
    "data": {
        "resourceUri": _AZURE_SA_URI,
        "operationName": ("Microsoft.Storage/storageAccounts/delete"),
        "status": "Succeeded",
    },
    "eventTime": "2026-01-01T00:00:00Z",
}


class TestNormalizeEvent:
    """Event normalization tests."""

    @pytest.mark.parametrize(
        "cloud,event_data,expected_type,expected_change",
        [
            ("gcp", GCP_CAI_CREATE_EVENT, "google_compute_instance", "create"),
            ("gcp", GCP_CAI_UPDATE_EVENT, "google_compute_instance", "update"),
            ("aws", AWS_CONFIG_CREATE_EVENT, "aws_instance", "create"),
            ("azure", AZURE_WRITE_EVENT, "azurerm_virtual_machine", "update"),
        ],
    )
    def test_normalize_event(
        self,
        cloud: str,
        event_data: dict,  # type: ignore[type-arg]
        expected_type: str,
        expected_change: str,
    ) -> None:
        result = normalize_event(cloud, event_data)
        assert result.resource_type == expected_type
        assert result.change_type == expected_change

    def test_normalize_unknown_resource_type_uses_raw(self) -> None:
        event = {
            "asset": {
                "name": "//unknown.googleapis.com/projects/p/things/t1",
                "assetType": "unknown.googleapis.com/Thing",
                "resource": {"data": {}},
            },
            "priorAsset": None,
            "window": {"startTime": "2026-01-01T00:00:00Z"},
        }
        result = normalize_event("gcp", event)
        assert result.resource_type == "unknown.googleapis.com/Thing"

    def test_normalize_unknown_cloud_raises(self) -> None:
        with pytest.raises(ValueError, match="Unknown cloud"):
            normalize_event("alibaba", {})

    def test_gcp_extract_project_id(self) -> None:
        result = normalize_event("gcp", GCP_CAI_CREATE_EVENT)
        assert result.cloud_account_id == "my-proj"

    def test_aws_extract_account_id(self) -> None:
        result = normalize_event("aws", AWS_CONFIG_CREATE_EVENT)
        assert result.cloud_account_id == "123456789012"

    def test_azure_extract_subscription_id(self) -> None:
        result = normalize_event("azure", AZURE_WRITE_EVENT)
        assert result.cloud_account_id == "sub-123"

    def test_gcp_delete_event(self) -> None:
        result = normalize_event("gcp", GCP_CAI_DELETE_EVENT)
        assert result.change_type == "delete"

    def test_aws_delete_event(self) -> None:
        result = normalize_event("aws", AWS_CONFIG_DELETE_EVENT)
        assert result.change_type == "delete"

    def test_azure_delete_event(self) -> None:
        result = normalize_event("azure", AZURE_DELETE_EVENT)
        assert result.change_type == "delete"
