"""Unit tests for AWSClient."""

import pytest
from botocore.exceptions import ClientError
from moto import mock_aws

from ai_org.core.aws_client import AWSClient


@pytest.mark.unit
def test_default_profile_and_region():
    """AWSClient should default to profile='org' and region='us-east-1'."""
    client = AWSClient()
    assert client.profile == "org"
    assert client.region == "us-east-1"


@pytest.mark.unit
def test_custom_profile_and_region():
    """AWSClient should accept custom profile and region values."""
    client = AWSClient(profile="custom", region="eu-west-1")
    assert client.profile == "custom"
    assert client.region == "eu-west-1"


@pytest.mark.unit
def test_session_lazy_creation():
    """The internal _session should be None until the session property is accessed."""
    client = AWSClient()
    assert client._session is None


@pytest.mark.unit
@mock_aws
def test_session_reuses():
    """Accessing .session twice should return the same session object."""
    client = AWSClient(profile=None)
    session_a = client.session
    session_b = client.session
    assert session_a is session_b


@pytest.mark.unit
@mock_aws
def test_client_creates_service_client():
    """client('sts') should return a usable boto3 service client."""
    aws = AWSClient(profile=None)
    sts = aws.client("sts")
    assert sts is not None
    # Verify it has the expected API
    assert hasattr(sts, "get_caller_identity")


@pytest.mark.unit
@mock_aws
def test_get_caller_identity():
    """get_caller_identity() should return a dict containing an Account key."""
    aws = AWSClient(profile=None)
    identity = aws.get_caller_identity()
    assert "Account" in identity


@pytest.mark.unit
@mock_aws
def test_get_account_id():
    """get_account_id() should return a string account ID."""
    aws = AWSClient(profile=None)
    account_id = aws.get_account_id()
    assert isinstance(account_id, str)
    assert len(account_id) > 0


@pytest.mark.unit
@mock_aws
def test_get_region():
    """get_region() should return the configured region."""
    aws = AWSClient(profile=None, region="us-west-2")
    assert aws.get_region() == "us-west-2"


@pytest.mark.unit
def test_handle_error_access_denied():
    """handle_error should produce a message for AccessDenied errors."""
    aws = AWSClient()
    error = ClientError(
        {"Error": {"Code": "AccessDenied", "Message": "not allowed"}},
        "SomeOperation",
    )
    msg = aws.handle_error(error, "default msg")
    assert "Access denied" in msg
    assert "not allowed" in msg


@pytest.mark.unit
def test_handle_error_not_found():
    """handle_error should produce a message for ResourceNotFoundException."""
    aws = AWSClient()
    error = ClientError(
        {"Error": {"Code": "ResourceNotFoundException", "Message": "gone"}},
        "SomeOperation",
    )
    msg = aws.handle_error(error, "default msg")
    assert "not found" in msg.lower()
    assert "gone" in msg


@pytest.mark.unit
def test_handle_error_unknown():
    """handle_error should fall back to the default message for unknown codes."""
    aws = AWSClient()
    error = ClientError(
        {"Error": {"Code": "SomethingWeird", "Message": "details"}},
        "SomeOperation",
    )
    msg = aws.handle_error(error, "fallback message")
    assert "fallback message" in msg
    assert "details" in msg


@pytest.mark.unit
@mock_aws
def test_session_fallback_on_profile_not_found():
    """When the named profile does not exist, AWSClient falls back to a default session."""
    aws = AWSClient(profile="nonexistent-profile-xyz")
    # Should not raise -- it falls back to a default session
    session = aws.session
    assert session is not None
