"""Integration tests for ECMSecurityAsync.

Requires a running ECM server at localhost:4000.
"""

import unittest
from typing import ClassVar

from ecmind_blue_client.ecm import ECM, ECMGroup, ECMSystemRole, ECMUser, ECMUserAttributes
from ecmind_blue_client.pool import AsyncPoolClient
from tests._test_settings import ECM_SERVERS, ECM_USERNAME, ECM_PASSWORD


class TestEcmSecurityAsync(unittest.IsolatedAsyncioTestCase):
    """Integration tests for ECMSecurityAsync — requires localhost:4000."""

    _cache_ready: ClassVar[bool] = False
    _roles: ClassVar[list[ECMSystemRole]]
    _users: ClassVar[list[ECMUser]]
    _user_groups: ClassVar[list[ECMGroup]]
    _user_groups_unknown: ClassVar[list[ECMGroup]]
    _groups: ClassVar[list[ECMGroup]]
    _group_standard: ClassVar[ECMGroup | None]
    _group_unknown: ClassVar[ECMGroup | None]
    _group_members: ClassVar[list[ECMUser]]
    _group_members_unknown: ClassVar[list[ECMUser]]
    _user_root: ClassVar[ECMUserAttributes | None]
    _user_unknown: ClassVar[ECMUserAttributes | None]

    @classmethod
    def setUpClass(cls):
        cls.client = AsyncPoolClient(servers=ECM_SERVERS, username=ECM_USERNAME, password=ECM_PASSWORD)
        cls.ecm = ECM(cls.client)

    @classmethod
    def tearDownClass(cls):
        del cls.client

    async def asyncSetUp(self):
        cls = self.__class__
        if cls._cache_ready:
            return
        cls._roles = await self.ecm.security.roles()
        cls._users = await self.ecm.security.users()
        cls._user_groups = await self.ecm.security.user_groups("CB870C5C6E2A491EA853D7C36D61C06B")
        cls._user_groups_unknown = await self.ecm.security.user_groups("1ECC63AFD2B041679126ABC501AAE130")
        cls._groups = await self.ecm.security.groups()
        cls._group_standard = await self.ecm.security.group("STANDARD")
        cls._group_unknown = await self.ecm.security.group("NONEXISTENT_GROUP_XYZ")
        cls._group_members = await self.ecm.security.group_members("STANDARD")
        cls._group_members_unknown = await self.ecm.security.group_members("NONEXISTENT_GROUP_XYZ")
        cls._user_root = await self.ecm.security.user("ROOT")
        cls._user_unknown = await self.ecm.security.user("NONEXISTENT_USER_XYZ")
        cls._cache_ready = True

    # ── roles ────────────────────────────────────────────────────────

    async def test_roles_returns_list(self):
        self.assertIsInstance(self._roles, list)

    async def test_roles_items_are_ecm_system_roles(self):
        for role in self._roles:
            self.assertIsInstance(role, ECMSystemRole)

    async def test_roles_root_has_roles(self):
        self.assertGreater(len(self._roles), 0)

    async def test_roles_root_has_admin_start(self):
        self.assertIn(ECMSystemRole.ADMIN_START, self._roles)

    # ── users ─────────────────────────────────────────────────────────

    async def test_users_returns_list(self):
        self.assertIsInstance(self._users, list)

    async def test_users_items_are_ecm_users(self):
        for user in self._users:
            self.assertIsInstance(user, ECMUser)

    async def test_users_not_empty(self):
        self.assertGreater(len(self._users), 0)

    async def test_users_have_guid(self):
        for user in self._users:
            self.assertGreater(len(user.guid), 0)

    # ── user_groups ───────────────────────────────────────────────────────────

    async def test_user_groups_returns_list(self):
        self.assertIsInstance(self._user_groups, list)

    async def test_user_groups_items_are_ecm_groups(self):
        for group in self._user_groups:
            self.assertIsInstance(group, ECMGroup)

    async def test_user_groups_have_name(self):
        for group in self._user_groups:
            self.assertGreater(len(group.name), 0)

    async def test_user_groups_no_groups_for_unknown_user(self):
        self.assertIsInstance(self._user_groups_unknown, list)

    # ── groups ────────────────────────────────────────────────────────────────

    async def test_groups_returns_list(self):
        self.assertIsInstance(self._groups, list)

    async def test_groups_not_empty(self):
        self.assertGreater(len(self._groups), 0)

    async def test_groups_items_are_ecm_groups(self):
        for group in self._groups:
            self.assertIsInstance(group, ECMGroup)

    async def test_groups_have_name(self):
        for group in self._groups:
            self.assertGreater(len(group.name), 0)

    # ── group ─────────────────────────────────────────────────────────────────

    async def test_group_returns_instance(self):
        self.assertIsInstance(self._group_standard, ECMGroup)

    async def test_group_name_matches(self):
        assert self._group_standard is not None
        self.assertEqual(self._group_standard.name, "STANDARD")

    async def test_group_unknown_returns_none(self):
        self.assertIsNone(self._group_unknown)

    # ── group_members ─────────────────────────────────────────────────────────

    async def test_group_members_returns_list(self):
        self.assertIsInstance(self._group_members, list)

    async def test_group_members_not_empty(self):
        self.assertGreater(len(self._group_members), 0)

    async def test_group_members_items_are_ecm_users(self):
        for user in self._group_members:
            self.assertIsInstance(user, ECMUser)

    async def test_group_members_unknown_group_returns_empty(self):
        self.assertIsInstance(self._group_members_unknown, list)

    # ── get_user_attributes ───────────────────────────────────────────────────

    async def test_get_user_attributes_returns_instance(self):
        self.assertIsInstance(self._user_root, ECMUserAttributes)

    async def test_get_user_attributes_has_guid(self):
        assert self._user_root is not None
        self.assertGreater(len(self._user_root.guid), 0)

    async def test_get_user_attributes_username_matches(self):
        assert self._user_root is not None
        self.assertEqual(self._user_root.username, "ROOT")

    async def test_get_user_attributes_unknown_user_returns_none(self):
        self.assertIsNone(self._user_unknown)
