from unittest import mock

from prowler.providers.aws.services.ssm.ssm_service import Document
from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_US_EAST_1


class Test_ssm_documents_set_as_public:
    def test_no_documents(self):
        ssm_client = mock.MagicMock
        ssm_client.documents = {}
        with mock.patch(
            "prowler.providers.aws.services.ssm.ssm_service.SSM",
            new=ssm_client,
        ):
            # Test Check
            from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
                ssm_documents_set_as_public,
            )

            check = ssm_documents_set_as_public()
            result = check.execute()

            assert len(result) == 0

    def test_document_public_account_owners(self):
        ssm_client = mock.MagicMock
        document_name = "test-document"
        document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
        ssm_client.audited_account = AWS_ACCOUNT_NUMBER
        ssm_client.documents = {
            document_name: Document(
                arn=document_arn,
                name=document_name,
                region=AWS_REGION_US_EAST_1,
                content="",
                account_owners=["111111111111", "111111222222"],
            )
        }
        with mock.patch(
            "prowler.providers.aws.services.ssm.ssm_service.SSM",
            new=ssm_client,
        ):
            # Test Check
            from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
                ssm_documents_set_as_public,
            )

            check = ssm_documents_set_as_public()
            result = check.execute()

            assert len(result) == 1
            assert result[0].region == AWS_REGION_US_EAST_1
            assert result[0].resource_id == document_name
            assert result[0].resource_arn == document_arn
            assert result[0].status == "FAIL"
            assert (
                result[0].status_extended
                == f"SSM Document {document_name} is shared to non-trusted AWS accounts: 111111111111, 111111222222."
            )

    def test_document_public_all_account_owners(self):
        ssm_client = mock.MagicMock
        document_name = "test-document"
        document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
        ssm_client.audited_account = AWS_ACCOUNT_NUMBER
        ssm_client.documents = {
            document_name: Document(
                arn=document_arn,
                name=document_name,
                region=AWS_REGION_US_EAST_1,
                content="",
                account_owners=["all"],
            )
        }
        with mock.patch(
            "prowler.providers.aws.services.ssm.ssm_service.SSM",
            new=ssm_client,
        ):
            # Test Check
            from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
                ssm_documents_set_as_public,
            )

            check = ssm_documents_set_as_public()
            result = check.execute()

            assert len(result) == 1
            assert result[0].region == AWS_REGION_US_EAST_1
            assert result[0].resource_id == document_name
            assert result[0].resource_arn == document_arn
            assert result[0].status == "FAIL"
            assert (
                result[0].status_extended == f"SSM Document {document_name} is public."
            )

    def test_document_public_to_other_trusted_AWS_accounts(self):
        ssm_client = mock.MagicMock
        document_name = "test-document"
        document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
        ssm_client.audited_account = AWS_ACCOUNT_NUMBER
        ssm_client.documents = {
            document_name: Document(
                arn=document_arn,
                name=document_name,
                region=AWS_REGION_US_EAST_1,
                content="",
                account_owners=["111111111333", "111111222444"],
            )
        }
        ssm_client.audit_config = {
            "trusted_account_ids": ["111111111333", "111111222444"]
        }
        with mock.patch(
            "prowler.providers.aws.services.ssm.ssm_service.SSM",
            new=ssm_client,
        ):
            # Test Check
            from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
                ssm_documents_set_as_public,
            )

            check = ssm_documents_set_as_public()
            result = check.execute()

            assert len(result) == 1
            assert result[0].region == AWS_REGION_US_EAST_1
            assert result[0].resource_id == document_name
            assert result[0].resource_arn == document_arn
            assert result[0].status == "PASS"
            assert (
                result[0].status_extended
                == f"SSM Document {document_name} is shared to trusted AWS accounts: 111111111333, 111111222444."
            )

    def test_document_public_to_self_account(self):
        ssm_client = mock.MagicMock
        document_name = "test-document"
        document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
        ssm_client.audited_account = AWS_ACCOUNT_NUMBER
        ssm_client.documents = {
            document_name: Document(
                arn=document_arn,
                name=document_name,
                region=AWS_REGION_US_EAST_1,
                content="",
                account_owners=[AWS_ACCOUNT_NUMBER],
            )
        }
        with mock.patch(
            "prowler.providers.aws.services.ssm.ssm_service.SSM",
            new=ssm_client,
        ):
            # Test Check
            from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
                ssm_documents_set_as_public,
            )

            check = ssm_documents_set_as_public()
            result = check.execute()

            assert len(result) == 1
            assert result[0].region == AWS_REGION_US_EAST_1
            assert result[0].resource_id == document_name
            assert result[0].resource_arn == document_arn
            assert result[0].status == "PASS"
            assert (
                result[0].status_extended
                == f"SSM Document {document_name} is not public."
            )

    def test_document_not_public(self):
        ssm_client = mock.MagicMock
        document_name = "test-document"
        document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
        ssm_client.audited_account = AWS_ACCOUNT_NUMBER
        ssm_client.documents = {
            document_name: Document(
                arn=document_arn,
                name=document_name,
                region=AWS_REGION_US_EAST_1,
                content="",
                account_owners=[],
            )
        }
        with mock.patch(
            "prowler.providers.aws.services.ssm.ssm_service.SSM",
            new=ssm_client,
        ):
            # Test Check
            from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
                ssm_documents_set_as_public,
            )

            check = ssm_documents_set_as_public()
            result = check.execute()

            assert len(result) == 1
            assert result[0].region == AWS_REGION_US_EAST_1
            assert result[0].resource_id == document_name
            assert result[0].resource_arn == document_arn
            assert result[0].status == "PASS"
            assert (
                result[0].status_extended
                == f"SSM Document {document_name} is not public."
            )
