"""Resource ID normalization: cloud-native format -> Terraform address.

Maps SCC, Security Hub, and Azure Defender resource identifiers to
Terraform resource addresses for cross-validation matching.
"""

from __future__ import annotations

__all__ = [
    "AZURE_RESOURCE_MAP",
    "SCC_RESOURCE_TYPE_MAP",
    "SECURITY_HUB_RESOURCE_MAP",
    "normalize_azure_resource",
    "normalize_scc_resource",
    "normalize_security_hub_resource",
]

SCC_RESOURCE_TYPE_MAP: dict[str, str] = {
    "compute.googleapis.com/Instance": "google_compute_instance",
    "sqladmin.googleapis.com/Instance": "google_sql_database_instance",
    "storage.googleapis.com/Bucket": "google_storage_bucket",
    "container.googleapis.com/Cluster": "google_container_cluster",
    "cloudkms.googleapis.com/CryptoKey": "google_kms_crypto_key",
    "iam.googleapis.com/ServiceAccount": "google_service_account",
}

SECURITY_HUB_RESOURCE_MAP: dict[str, str] = {
    "AwsRdsDbInstance": "aws_db_instance",
    "AwsS3Bucket": "aws_s3_bucket",
    "AwsEc2Instance": "aws_instance",
    "AwsIamRole": "aws_iam_role",
    "AwsLambdaFunction": "aws_lambda_function",
    "AwsEksCluster": "aws_eks_cluster",
    "AwsElbv2LoadBalancer": "aws_lb",
    "AwsEc2SecurityGroup": "aws_security_group",
    "AwsKmsKey": "aws_kms_key",
}

AZURE_RESOURCE_MAP: dict[str, str] = {
    "Microsoft.Sql/servers": "azurerm_mssql_server",
    "Microsoft.Storage/storageAccounts": "azurerm_storage_account",
    "Microsoft.Compute/virtualMachines": "azurerm_virtual_machine",
    "Microsoft.KeyVault/vaults": "azurerm_key_vault",
    "Microsoft.ContainerService/managedClusters": "azurerm_kubernetes_cluster",
    "Microsoft.Network/networkSecurityGroups": "azurerm_network_security_group",
    "Microsoft.Web/sites": "azurerm_linux_web_app",
}


def normalize_scc_resource(scc_resource_name: str) -> str | None:
    """Convert SCC resource name -> Terraform address.

    Input format: //service.googleapis.com/projects/{project}/.../{type}/{name}
    Returns "{terraform_type}.{name}" or None if unmappable.
    """
    # Strip leading "//"
    stripped = scc_resource_name.lstrip("/")
    # Split on first "/" to get service domain and path
    slash_idx = stripped.find("/")
    if slash_idx == -1:
        return None
    service_domain = stripped[:slash_idx]
    path = stripped[slash_idx + 1 :]

    # Extract service prefix from domain (e.g., "compute.googleapis.com")
    # Try to find a matching resource type from the path segments
    segments = path.split("/")
    if len(segments) < 2:
        return None

    # Resource name is the last segment
    resource_name = segments[-1]

    # Resource type key is "service_domain/ResourceType"
    # The resource type is the second-to-last segment (plural) mapped to singular
    # SCC uses: service.googleapis.com/Type (e.g., compute.googleapis.com/Instance)
    # We need to check each known key against the resource name
    for scc_type, tf_type in SCC_RESOURCE_TYPE_MAP.items():
        # scc_type is like "compute.googleapis.com/Instance"
        scc_service, scc_resource = scc_type.split("/", 1)
        if service_domain == scc_service:
            # Check if path contains this resource type
            # (case-insensitive plural match)
            for _, seg in enumerate(segments[:-1]):
                lower_seg = seg.lower()
                lower_res = scc_resource.lower()
                if lower_seg == lower_res + "s" or lower_seg == lower_res:
                    return f"{tf_type}.{resource_name}"
    return None


def normalize_security_hub_resource(
    resource_id: str,
    resource_type: str,
) -> str | None:
    """Convert AWS Security Hub ARN -> Terraform address.

    Returns "{terraform_type}.{name}" or None if unmappable.
    """
    tf_type = SECURITY_HUB_RESOURCE_MAP.get(resource_type)
    if tf_type is None:
        return None

    # Extract name from ARN last segment
    # ARN format: arn:aws:service:region:account:resource-type/name or :name
    parts = resource_id.split(":")
    if not parts:
        return None
    last = parts[-1]
    # Handle both "/" and ":" separators in resource part
    resource_name = last.rsplit("/", 1)[-1] if "/" in last else last

    return f"{tf_type}.{resource_name}"


def normalize_azure_resource(resource_id: str) -> str | None:
    """Convert Azure resource ID -> Terraform address.

    Input format: /subscriptions/{sub}/resourceGroups/{rg}/
    providers/{namespace}/{type}/{name}
    Returns "{terraform_type}.{name}" or None if unmappable.
    """
    # Parse the resource ID path
    segments = resource_id.strip("/").split("/")

    # Find "providers" segment to locate namespace and type
    provider_idx = None
    for i, seg in enumerate(segments):
        if seg.lower() == "providers":
            provider_idx = i
            break

    if provider_idx is None:
        return None

    # Need at least namespace, type, and name after "providers"
    remaining = segments[provider_idx + 1 :]
    if len(remaining) < 3:
        return None

    # namespace/type format: "Microsoft.Sql/servers"
    namespace = remaining[0]
    resource_type = remaining[1]
    resource_name = remaining[2]

    azure_key = f"{namespace}/{resource_type}"
    tf_type = AZURE_RESOURCE_MAP.get(azure_key)
    if tf_type is None:
        return None

    return f"{tf_type}.{resource_name}"
