"""Tests for authentication validation helpers."""

from unittest.mock import MagicMock, patch

import pytest

from azure_discovery.adt_types import AzureDiscoveryRequest, AzureEnvironment
from azure_discovery.utils.auth_validation import validate_auth


@pytest.fixture
def request_public() -> AzureDiscoveryRequest:
    return AzureDiscoveryRequest(
        tenant_id="tenant-1",
        environment=AzureEnvironment.AZURE_PUBLIC,
    )


@patch("azure_discovery.utils.auth_validation.get_credential")
@patch("azure_discovery.utils.auth_validation.build_environment_config")
def test_validate_auth_success(
    mock_build_config: MagicMock,
    mock_get_credential: MagicMock,
    request_public: AzureDiscoveryRequest,
) -> None:
    """Validate auth returns ok when both ARM and Graph tokens succeed."""
    mock_build_config.return_value.resource_manager = "https://management.azure.com/"
    mock_build_config.return_value.graph_endpoint = "https://graph.microsoft.com/"
    cred = MagicMock()
    cred.get_token = MagicMock(return_value=MagicMock(token="token"))
    mock_get_credential.return_value = cred

    result = validate_auth(request_public)

    assert result["ok"] is True
    assert result["environment"] == "azure_public"
    assert result["probe_connectivity"] is False
    assert len(result["scopes"]) == 2
    assert "errors" not in result


@patch("azure_discovery.utils.auth_validation.get_credential")
@patch("azure_discovery.utils.auth_validation.build_environment_config")
def test_validate_auth_arm_failure(
    mock_build_config: MagicMock,
    mock_get_credential: MagicMock,
    request_public: AzureDiscoveryRequest,
) -> None:
    """Validate auth returns errors when ARM token fails."""
    mock_build_config.return_value.resource_manager = "https://management.azure.com/"
    mock_build_config.return_value.graph_endpoint = "https://graph.microsoft.com/"
    cred = MagicMock()
    cred.get_token = MagicMock(side_effect=[Exception("ARM failed"), MagicMock(token="t")])
    mock_get_credential.return_value = cred

    result = validate_auth(request_public)

    assert result["ok"] is False
    assert "errors" in result
    assert any("ARM" in e for e in result["errors"])
    assert len(result["scopes"]) == 1


@patch("azure_discovery.utils.auth_validation.get_credential")
@patch("azure_discovery.utils.auth_validation.build_environment_config")
def test_validate_auth_graph_failure(
    mock_build_config: MagicMock,
    mock_get_credential: MagicMock,
    request_public: AzureDiscoveryRequest,
) -> None:
    """Validate auth returns errors when Graph token fails."""
    mock_build_config.return_value.resource_manager = "https://management.azure.com/"
    mock_build_config.return_value.graph_endpoint = "https://graph.microsoft.com/"
    cred = MagicMock()
    cred.get_token = MagicMock(side_effect=[MagicMock(token="t"), Exception("Graph failed")])
    mock_get_credential.return_value = cred

    result = validate_auth(request_public)

    assert result["ok"] is False
    assert "errors" in result
    assert any("Graph" in e for e in result["errors"])
    assert len(result["scopes"]) == 1


@patch("azure_discovery.utils.auth_validation.get_credential")
@patch("azure_discovery.utils.auth_validation.build_environment_config")
def test_validate_auth_both_fail(
    mock_build_config: MagicMock,
    mock_get_credential: MagicMock,
    request_public: AzureDiscoveryRequest,
) -> None:
    """Validate auth returns both errors when both tokens fail."""
    mock_build_config.return_value.resource_manager = "https://management.azure.com/"
    mock_build_config.return_value.graph_endpoint = "https://graph.microsoft.com/"
    cred = MagicMock()
    cred.get_token = MagicMock(side_effect=Exception("token failed"))
    mock_get_credential.return_value = cred

    result = validate_auth(request_public)

    assert result["ok"] is False
    assert len(result["errors"]) == 2
    assert result["scopes"] == []


@patch("azure_discovery.utils.auth_validation.get_credential")
@patch("azure_discovery.utils.auth_validation.build_environment_config")
def test_validate_auth_probe_connectivity_flag(
    mock_build_config: MagicMock,
    mock_get_credential: MagicMock,
    request_public: AzureDiscoveryRequest,
) -> None:
    """Validate auth passes probe_connectivity through in payload."""
    mock_build_config.return_value.resource_manager = "https://management.azure.com/"
    mock_build_config.return_value.graph_endpoint = "https://graph.microsoft.com/"
    cred = MagicMock()
    cred.get_token = MagicMock(return_value=MagicMock(token="token"))
    mock_get_credential.return_value = cred

    result = validate_auth(request_public, probe_connectivity=True)

    assert result["probe_connectivity"] is True
