# tests/test_policies_automated.py
import unittest

from anypoint_sdk._http import HttpClient
from anypoint_sdk.resources.policies import Policies
from tests.fakes import FakeSession
from tests.helpers import make_response

BASE = "https://api.test.local"


class PoliciesAutomatedTests(unittest.TestCase):
    def test_list_environment_automated_policies_normalises_dedupes_and_filters(self):
        org_id = "o1"
        env_id = "e1"
        payload = {
            "automatedPolicies": [
                {
                    "audit": {"created": {"date": "2025-08-13T14:20:55.647Z"}},
                    "id": 129720,
                    "ruleOfApplication": {
                        "environmentId": env_id,
                        "organizationId": org_id,
                    },
                    "groupId": "68ef9520-24e9-4cf2-b2f5-620025690913",
                    "assetId": "ip-allowlist",
                    "assetVersion": "1.1.1",
                    "configurationData": {
                        "ipExpression": "#[attributes.headers['x-forwarded-for']]"
                    },
                    "order": 2,
                    "disabled": False,
                    "implementationAssets": [
                        {
                            "name": "IP Allowlist - Flex",
                            "assetId": "ip-allowlist-flex",
                            "version": "1.2.0",
                            "technology": "flexGateway",
                        },
                        {
                            "name": "IP Allowlist - Mule4",
                            "assetId": "ip-allowlist-mule",
                            "version": "1.2.0",
                            "technology": "mule4",
                        },
                        {
                            "name": "IP Allowlist - Mule4",
                            "assetId": "ip-allowlist-mule",
                            "version": "1.1.0",
                            "technology": "mule4",
                        },
                    ],
                },
                # duplicate id to prove dedupe
                {
                    "id": 129720,
                    "ruleOfApplication": {
                        "environmentId": env_id,
                        "organizationId": org_id,
                    },
                    "assetId": "ip-allowlist",
                    "assetVersion": "1.1.1",
                },
                # other env, should be filtered out
                {
                    "id": 999999,
                    "ruleOfApplication": {
                        "environmentId": "e-other",
                        "organizationId": org_id,
                    },
                    "assetId": "something-else",
                    "assetVersion": "0.1.0",
                },
            ]
        }
        resp = make_response(
            status=200,
            json_body=payload,
            url=f"{BASE}/apimanager/api/v1/organizations/{org_id}/automated-policies",
        )
        http = HttpClient(base_url=BASE, session=FakeSession([resp]), retries=0)

        out = Policies(http).list_environment_automated_policies(org_id, env_id)

        self.assertEqual(len(out), 1)
        p = out[0]
        self.assertEqual(p["id"], 129720)
        self.assertEqual(p["assetId"], "ip-allowlist")
        self.assertEqual(p["assetVersion"], "1.1.1")
        self.assertEqual(p["order"], 2)
        self.assertFalse(p["disabled"])
        self.assertIsInstance(p["implementationAssets"], list)
        self.assertGreaterEqual(len(p["implementationAssets"]), 2)

    def test_list_environment_automated_policies_handles_missing_or_non_list(self):
        org_id = "o1"
        env_id = "e1"
        # no 'automatedPolicies' key
        resp1 = make_response(
            status=200,
            json_body={"total": 0},
            url=f"{BASE}/apimanager/api/v1/organizations/{org_id}/automated-policies",
        )
        http1 = HttpClient(base_url=BASE, session=FakeSession([resp1]), retries=0)
        out1 = Policies(http1).list_environment_automated_policies(org_id, env_id)
        self.assertEqual(out1, [])

        # automatedPolicies is not a list
        resp2 = make_response(
            status=200,
            json_body={"automatedPolicies": {"unexpected": True}},
            url=f"{BASE}/apimanager/api/v1/organizations/{org_id}/automated-policies",
        )
        http2 = HttpClient(base_url=BASE, session=FakeSession([resp2]), retries=0)
        out2 = Policies(http2).list_environment_automated_policies(org_id, env_id)
        self.assertEqual(out2, [])

    def test_list_environment_automated_policies_ignores_non_dict_entries(self):
        org_id = "o1"
        env_id = "e1"
        payload = {"automatedPolicies": ["bad", 123, None]}
        resp = make_response(
            status=200,
            json_body=payload,
            url=f"{BASE}/apimanager/api/v1/organizations/{org_id}/automated-policies",
        )
        http = HttpClient(base_url=BASE, session=FakeSession([resp]), retries=0)
        out = Policies(http).list_environment_automated_policies(org_id, env_id)
        self.assertEqual(out, [])

    def test_rule_of_application_is_dict_without_env_id(self):
        org_id = "o1"
        env_id = "e1"
        payload = {
            "automatedPolicies": [
                {
                    "id": 42,
                    "ruleOfApplication": {
                        "organizationId": org_id
                    },  # dict present, no environmentId
                    "assetId": "ip-allowlist",
                    "assetVersion": "1.0.0",
                    "implementationAssets": [{"assetId": "impl", "version": "1.0.0"}],
                }
            ]
        }
        resp = make_response(
            status=200,
            json_body=payload,
            url=f"{BASE}/apimanager/api/v1/organizations/{org_id}/automated-policies",
        )
        http = HttpClient(base_url=BASE, session=FakeSession([resp]), retries=0)
        out = Policies(http).list_environment_automated_policies(org_id, env_id)
        self.assertEqual(len(out), 1)
        self.assertEqual(out[0]["id"], 42)

    def test_rule_of_application_non_dict_path(self):
        org_id = "o1"
        env_id = "e1"
        payload = {
            "automatedPolicies": [
                {
                    "id": 77,
                    "ruleOfApplication": "unexpected-shape",  # NOT a dict, exercises false branch
                    "assetId": "some-policy",
                    "assetVersion": "0.1.0",
                }
            ]
        }
        resp = make_response(
            status=200,
            json_body=payload,
            url=f"{BASE}/apimanager/api/v1/organizations/{org_id}/automated-policies",
        )
        http = HttpClient(base_url=BASE, session=FakeSession([resp]), retries=0)
        out = Policies(http).list_environment_automated_policies(org_id, env_id)
        # Included because roa_env stays None
        self.assertEqual(len(out), 1)
        self.assertEqual(out[0]["id"], 77)


if __name__ == "__main__":
    unittest.main()
