# Path: repokid/datasource/plugin.py
# class DatasourcePlugin(RepokidPlugin, Generic[KT, VT]):
#     """A dict-like container that can be used to retrieve and store data"""
# 
#     _data: Dict[KT, VT]
#     _seeded: List[str]
# 
#     def __init__(self, config: Optional[RepokidConfig] = None):
#         super().__init__(config=config)
#         self._data = {}
#         self._seeded = []
# 
#     def __getitem__(self, name: KT) -> VT:
#         return self._data[name]
# 
#     def __iter__(self) -> Iterator[VT]:
#         return iter(cast(Iterable[VT], self._data))
# 
#     def keys(self) -> Iterable[KT]:
#         return self._data.keys()
# 
#     def items(self) -> ItemsView[KT, VT]:
#         return self._data.items()
# 
#     def values(self) -> ValuesView[VT]:
#         return self._data.values()
# 
#     def get(self, identifier: KT) -> VT:
#         raise NotImplementedError
# 
#     def seed(self, identifier: KT) -> Iterable[KT]:
#         raise NotImplementedError
# 
#     def reset(self) -> None:
#         logger.debug("resetting %s", type(self).__name__)
#         self._data = {}
#         self._seeded = []
# 
# Path: repokid/exceptions.py
# class AardvarkError(Exception):
#     pass
# 
# Path: repokid/exceptions.py
# class NotFoundError(Exception):
#     pass
# 
# Path: repokid/plugin.py
# class Singleton(M_A):
#     _instances: Dict[str, Singleton] = {}
# 
#     def __call__(cls, *args: Any, **kwargs: Any) -> Singleton:
#         if cls.__name__ not in cls._instances:
#             cls._instances[cls.__name__] = super(Singleton, cls).__call__(
#                 *args, **kwargs
#             )
#         return cls._instances[cls.__name__]
# 
# Path: repokid/types.py
# KT = TypeVar("KT")
# VT = TypeVar("VT")
# 
# Path: repokid/types.py
# KT = TypeVar("KT")
# VT = TypeVar("VT")
# 
# Path: repokid/types.py
# KT = TypeVar("KT")
# VT = TypeVar("VT")


import logging
import requests
from typing import Any
from typing import Dict
from typing import Iterable
from typing import Optional
from repokid.datasource.plugin import DatasourcePlugin
from repokid.exceptions import AardvarkError
from repokid.exceptions import NotFoundError
from repokid.plugin import Singleton
from repokid.types import AardvarkResponse
from repokid.types import AccessAdvisorEntry
from repokid.types import RepokidConfig

logger = logging.getLogger("repokid")


class AccessAdvisorDatasource(
    DatasourcePlugin[str, AccessAdvisorEntry], metaclass=Singleton
):
    def __init__(self, config: Optional[RepokidConfig] = None):
        super().__init__(config=config)

    def _fetch(
        self, account_number: str = "", arn: str = ""
    ) -> Dict[str, AccessAdvisorEntry]:
        """
        Make a request to the Aardvark server to get all data about a given account or ARN.
        We'll request in groups of PAGE_SIZE and check the current count to see if we're done. Keep requesting as long
        as the total count (reported by the API) is greater than the number of pages we've received times the page size.
        As we go, keeping building the dict and return it when done.

        Args:
            account_number (string): Used to form the phrase query for Aardvark
            arn (string)

        Returns:
            dict: Aardvark data is a dict with the role ARN as the key and a list of services as value
        """
        api_location = self.config.get("aardvark_api_location")
        if not api_location:
            raise AardvarkError("aardvark not configured")


# Path: repokid/datasource/plugin.py
# class DatasourcePlugin(RepokidPlugin, Generic[KT, VT]):
#     """A dict-like container that can be used to retrieve and store data"""
# 
#     _data: Dict[KT, VT]
#     _seeded: List[str]
# 
#     def __init__(self, config: Optional[RepokidConfig] = None):
#         super().__init__(config=config)
#         self._data = {}
#         self._seeded = []
# 
#     def __getitem__(self, name: KT) -> VT:
#         return self._data[name]
# 
#     def __iter__(self) -> Iterator[VT]:
#         return iter(cast(Iterable[VT], self._data))
# 
#     def keys(self) -> Iterable[KT]:
#         return self._data.keys()
# 
#     def items(self) -> ItemsView[KT, VT]:
#         return self._data.items()
# 
#     def values(self) -> ValuesView[VT]:
#         return self._data.values()
# 
#     def get(self, identifier: KT) -> VT:
#         raise NotImplementedError
# 
#     def seed(self, identifier: KT) -> Iterable[KT]:
#         raise NotImplementedError
# 
#     def reset(self) -> None:
#         logger.debug("resetting %s", type(self).__name__)
#         self._data = {}
#         self._seeded = []
# 
# Path: repokid/exceptions.py
# class AardvarkError(Exception):
#     pass
# 
# Path: repokid/exceptions.py
# class NotFoundError(Exception):
#     pass
# 
# Path: repokid/plugin.py
# class Singleton(M_A):
#     _instances: Dict[str, Singleton] = {}
# 
#     def __call__(cls, *args: Any, **kwargs: Any) -> Singleton:
#         if cls.__name__ not in cls._instances:
#             cls._instances[cls.__name__] = super(Singleton, cls).__call__(
#                 *args, **kwargs
#             )
#         return cls._instances[cls.__name__]
# 
# Path: repokid/types.py
# KT = TypeVar("KT")
# VT = TypeVar("VT")
# 
# Path: repokid/types.py
# KT = TypeVar("KT")
# VT = TypeVar("VT")
# 
# Path: repokid/types.py
# KT = TypeVar("KT")
# VT = TypeVar("VT")


# Path: repokid/datasource/access_advisor.py
import logging
import requests
from typing import Any
from typing import Dict
from typing import Iterable
from typing import Optional
from repokid.datasource.plugin import DatasourcePlugin
from repokid.exceptions import AardvarkError
from repokid.exceptions import NotFoundError
from repokid.plugin import Singleton
from repokid.types import AardvarkResponse
from repokid.types import AccessAdvisorEntry
from repokid.types import RepokidConfig


logger = logging.getLogger("repokid")


class AccessAdvisorDatasource(
    DatasourcePlugin[str, AccessAdvisorEntry], metaclass=Singleton
):
    def __init__(self, config: Optional[RepokidConfig] = None):
        super().__init__(config=config)

    def _fetch(
        self, account_number: str = "", arn: str = ""
    ) -> Dict[str, AccessAdvisorEntry]:
        """
        Make a request to the Aardvark server to get all data about a given account or ARN.
        We'll request in groups of PAGE_SIZE and check the current count to see if we're done. Keep requesting as long
        as the total count (reported by the API) is greater than the number of pages we've received times the page size.
        As we go, keeping building the dict and return it when done.

        Args:
            account_number (string): Used to form the phrase query for Aardvark
            arn (string)

        Returns:
            dict: Aardvark data is a dict with the role ARN as the key and a list of services as value
        """
        api_location = self.config.get("aardvark_api_location")
        if not api_location:
            raise AardvarkError("aardvark not configured")


        response_data: AardvarkResponse = {}