"""Tests for Microsoft Graph to ResourceNode mappers."""

from unittest.mock import MagicMock

import pytest

from azure_discovery.adt_types import ResourceNode
from azure_discovery.utils.graph_mappers import (
    application_to_node,
    conditional_access_policy_to_node,
    group_to_node,
    risky_user_to_node,
    service_principal_to_node,
)


def test_group_to_node_with_list_group_types() -> None:
    """group_to_node sets groupType from first element and groupTypes from list."""
    group = MagicMock()
    group.id = "g1"
    group.display_name = "Group One"
    group.mail = None
    group.group_types = ["Unified", "Dynamic"]

    node = group_to_node(group)

    assert node.type == "Microsoft.Graph/Group"
    assert node.tags["groupType"] == "Unified"
    assert node.tags["groupTypes"] == "Unified,Dynamic"


def test_group_to_node_with_non_list_group_types() -> None:
    """group_to_node sets groupType from scalar group_types."""
    group = MagicMock()
    group.id = "g2"
    group.displayName = "Group Two"
    group.mail = None
    group.group_types = None
    group.groupTypes = "Unified"

    node = group_to_node(group)

    assert node.tags["groupType"] == "Unified"


def test_application_to_node_with_app_id() -> None:
    """application_to_node includes appId in tags when present."""
    app = MagicMock()
    app.id = "app-1"
    app.display_name = "My App"
    app.app_id = "00000000-0000-0000-0000-000000000001"

    node = application_to_node(app)

    assert node.type == "Microsoft.Graph/Application"
    assert node.tags["appId"] == "00000000-0000-0000-0000-000000000001"


def test_service_principal_to_node_with_app_id() -> None:
    """service_principal_to_node includes appId in tags when present."""
    sp = MagicMock()
    sp.id = "sp-1"
    sp.displayName = "Service Principal"
    sp.app_id = None  # mapper tries app_id then appId
    sp.appId = "00000000-0000-0000-0000-000000000002"

    node = service_principal_to_node(sp)

    assert node.type == "Microsoft.Graph/ServicePrincipal"
    assert node.tags["appId"] == "00000000-0000-0000-0000-000000000002"


def test_conditional_access_policy_to_node_with_state() -> None:
    """conditional_access_policy_to_node includes state in tags when present."""
    policy = MagicMock()
    policy.id = "cap-1"
    policy.displayName = "Block Legacy"
    policy.state = "enabled"

    node = conditional_access_policy_to_node(policy)

    assert node.type == "Microsoft.Graph/ConditionalAccessPolicy"
    assert node.tags["state"] == "enabled"


def test_risky_user_to_node_with_risk_and_upn() -> None:
    """risky_user_to_node includes riskLevel, riskState, userPrincipalName in tags."""
    risky = MagicMock()
    risky.id = "ru-1"
    risky.user_display_name = "Risky User"
    risky.user_principal_name = None  # mapper tries user_principal_name then userPrincipalName
    risky.userPrincipalName = "user@contoso.com"
    risky.risk_level = "high"
    risky.risk_state = "confirmedCompromised"
    risky.riskLevel = "high"
    risky.riskState = "confirmedCompromised"

    node = risky_user_to_node(risky)

    assert node.type == "Microsoft.Graph/RiskyUser"
    assert node.tags["riskLevel"] == "high"
    assert node.tags["riskState"] == "confirmedCompromised"
    assert node.tags["userPrincipalName"] == "user@contoso.com"
    assert node.name == "Risky User"
