"""Azure Landing Zone (ALZ/SLZ) detection.

Contract:
- detect_azure_landing_zone() detects ALZ/SLZ via Resource Graph.
- Never raises — returns LandingZoneContext(detected=False) on error.
"""

from __future__ import annotations

import sys

from complyform.core.scanner.landing_zone import LandingZoneContext

__all__ = ["detect_azure_landing_zone"]

# Standard ALZ management group names
_ALZ_STANDARD_NAMES: set[str] = {
    "platform",
    "landing zones",
    "connectivity",
    "identity",
    "management",
    "corp",
    "online",
}


def detect_azure_landing_zone(
    subscription_id: str,
    credentials: object | None,
) -> LandingZoneContext:
    """Detect ALZ/SLZ via Resource Graph.

    Two queries:
    1. Management group hierarchy
    2. Inherited policies from management group scope
    Pattern match: >=3 of standard ALZ names -> type="alz"
    """
    try:
        import httpx  # noqa: F401
    except ImportError:
        print(
            "Warning: httpx not installed, skipping Azure LZ detection",
            file=sys.stderr,
        )
        return LandingZoneContext(cloud="azure", detected=False, type=None)

    try:
        from azure.mgmt.resourcegraph import (  # type: ignore
            ResourceGraphClient,
        )
        from azure.mgmt.resourcegraph.models import (  # type: ignore
            QueryRequest,
        )
    except ImportError:
        print(
            "Warning: azure-mgmt-resourcegraph not installed",
            file=sys.stderr,
        )
        return LandingZoneContext(cloud="azure", detected=False, type=None)

    try:
        rg_client = ResourceGraphClient(credentials)  # type: ignore[arg-type]

        # Query 1: Management group hierarchy
        mg_query = QueryRequest(
            query=(
                "resourcecontainers"
                " | where type == 'microsoft.management/managementgroups'"
                " | project name, properties.displayName"
            ),
            subscriptions=[subscription_id],
        )
        mg_result = rg_client.resources(mg_query)
        mg_names: set[str] = set()
        hierarchy: list[str] = []

        for row in mg_result.data:
            display_name = str(
                row.get("properties_displayName", row.get("name", ""))  # type: ignore[attr-defined]
            ).lower()
            mg_names.add(display_name)
            hierarchy.append(row.get("name", ""))  # type: ignore[attr-defined]

        # Pattern match: >=3 standard ALZ names
        matches = mg_names & _ALZ_STANDARD_NAMES
        if len(matches) < 3:
            return LandingZoneContext(cloud="azure", detected=False, type=None)

        lz_type = "alz"

        # Query 2: Inherited policies
        policy_query = QueryRequest(
            query=(
                "PolicyResources"
                " | where type == 'microsoft.authorization/policyassignments'"
                " | where properties.scope contains '/managementGroups/'"
                " | project name, properties.displayName,"
                " properties.enforcementMode, properties.policyDefinitionId"
            ),
            subscriptions=[subscription_id],
        )
        policy_result = rg_client.resources(policy_query)

        inherited_policies: list[str] = []
        drift_risk_policies: list[str] = []

        for row in policy_result.data:
            display_name = row.get("properties_displayName", row.get("name", ""))  # type: ignore[attr-defined]
            enforcement = row.get("properties_enforcementMode", "")  # type: ignore[attr-defined]
            policy_def = row.get("properties_policyDefinitionId", "")  # type: ignore[attr-defined]

            if enforcement == "Default":
                inherited_policies.append(str(display_name))

            # DeployIfNotExists policies create drift risk
            if "deployifnotexists" in str(policy_def).lower():
                drift_risk_policies.append(str(display_name))

        return LandingZoneContext(
            cloud="azure",
            detected=True,
            type=lz_type,
            inherited_policies=inherited_policies,
            hierarchy_path=hierarchy,
            drift_risk_policies=drift_risk_policies,
        )

    except Exception as exc:
        print(
            f"Warning: Azure landing zone detection failed: {exc}",
            file=sys.stderr,
        )
        return LandingZoneContext(cloud="azure", detected=False, type=None)
