"""Tests for AWS Control Tower landing zone detection."""

from __future__ import annotations

import sys
from unittest.mock import MagicMock, patch


class TestAWSLandingZone:
    def test_no_boto3(self) -> None:
        from complyform.core.scanner.landing_zone_aws import detect_aws_landing_zone

        with patch("builtins.__import__", side_effect=ImportError):
            result = detect_aws_landing_zone("123456789", None)
        assert result.detected is False

    def test_no_organization(self) -> None:
        # Create mock botocore module with ClientError
        mock_botocore = MagicMock()

        class _ClientError(Exception):
            def __init__(self, error_response: dict, operation_name: str) -> None:
                self.response = error_response
                self.operation_name = operation_name
                super().__init__(f"{operation_name}: {error_response}")

        mock_botocore.exceptions.ClientError = _ClientError

        mock_boto3 = MagicMock()
        mock_session = MagicMock()
        mock_client = MagicMock()
        mock_session.client.return_value = mock_client
        mock_client.describe_organization.side_effect = _ClientError(
            {"Error": {"Code": "AWSOrganizationsNotInUseException", "Message": ""}},
            "DescribeOrganization",
        )

        with patch.dict(
            sys.modules,
            {
                "boto3": mock_boto3,
                "botocore": mock_botocore,
                "botocore.exceptions": mock_botocore.exceptions,
            },
        ):
            # Re-import to pick up mocked modules
            import importlib

            import complyform.core.scanner.landing_zone_aws as mod

            importlib.reload(mod)
            result = mod.detect_aws_landing_zone("123456789", mock_session)

        assert result.detected is False

    def test_api_error_returns_not_detected(self) -> None:
        mock_boto3 = MagicMock()
        mock_botocore = MagicMock()
        mock_botocore.exceptions.ClientError = type("ClientError", (Exception,), {})

        mock_session = MagicMock()
        mock_session.client.return_value.describe_organization.side_effect = Exception(
            "boom"
        )

        with patch.dict(
            sys.modules,
            {
                "boto3": mock_boto3,
                "botocore": mock_botocore,
                "botocore.exceptions": mock_botocore.exceptions,
            },
        ):
            import importlib

            import complyform.core.scanner.landing_zone_aws as mod

            importlib.reload(mod)
            result = mod.detect_aws_landing_zone("123456789", mock_session)

        assert result.detected is False

    def test_control_tower_detected(self) -> None:
        mock_boto3 = MagicMock()
        mock_botocore = MagicMock()
        mock_botocore.exceptions.ClientError = type("ClientError", (Exception,), {})

        mock_session = MagicMock()
        mock_client = MagicMock()
        mock_session.client.return_value = mock_client
        mock_client.describe_organization.return_value = {
            "Organization": {"Id": "o-123"}
        }
        mock_client.list_roots.return_value = {"Roots": [{"Id": "r-123"}]}
        mock_client.list_organizational_units_for_parent.return_value = {
            "OrganizationalUnits": [
                {"Name": "Security", "Id": "ou-1"},
                {"Name": "Sandbox", "Id": "ou-2"},
            ]
        }
        mock_client.list_policies_for_target.return_value = {
            "Policies": [{"Name": "deny-public-s3"}]
        }

        with patch.dict(
            sys.modules,
            {
                "boto3": mock_boto3,
                "botocore": mock_botocore,
                "botocore.exceptions": mock_botocore.exceptions,
            },
        ):
            import importlib

            import complyform.core.scanner.landing_zone_aws as mod

            importlib.reload(mod)
            result = mod.detect_aws_landing_zone("123456789", mock_session)

        assert result.detected is True
        assert result.type == "control_tower"
        assert "deny-public-s3" in result.inherited_policies
