## This is an auto-generated file. Do not edit this file directly.
import asyncio
import importlib.metadata
import logging
import os
import platform
import sys

from types import TracebackType
from typing import Optional, Type, TYPE_CHECKING

import httpx

from komodo.auth.Session import Session

from komodo.api_client import ApiClient
from komodo.configuration import Configuration

if TYPE_CHECKING:
    from komodo.api.iam_api import IamApi


class Client:
    def __init__(
        self,
        account_id: str = None,
        auth_session: Session | None = None,
        **kwargs,
    ):
        """

        :param account_id
        :param auth_session: optional Komodo Platform session
        """
        self._logger = logging.getLogger(__name__)
        self._auth_session = auth_session if auth_session is not None else Session()

        self._auth_session.connect()

        self.x_account_id = account_id if account_id is not None else self._auth_session.account_id

        self._client_session = self.komodo_api_client()

    def komodo_api_client(self) -> ApiClient:
        access_token = self._auth_session._token_data.access_token
        configuration = Configuration(
            api_key={"JWT": access_token, "HTTPBearer": access_token, "x-account-id": self.x_account_id}, api_key_prefix={"JWT": "Bearer", "HTTPBearer": "Bearer"}, access_token=access_token
        )
        configuration.refresh_api_key_hook = self.refresh_api_key_hook

        client = ApiClient(configuration, header_name="X-API-Version", header_value="2024-10-01")

        if "HOSTNAME" in os.environ:
            client.set_default_header("X-KH-Compute-ContainerID", os.environ["HOSTNAME"])

        version = importlib.metadata.version("komodo")
        system_info = self.get_system_info()

        user_agent = f"KomodoSDK/{version} ({system_info})"
        client.user_agent = user_agent
        return client

    @property
    def logger(self):
        """
        SDK session logger
        """
        return self._logger

    @property
    def auth(self) -> Session:
        """
        SDK auth session
        """
        return self._auth_session

    @property
    def session(self) -> httpx.AsyncClient:
        """
        SDK HTTP session
        """
        return self._client_session

    @classmethod
    async def create(
        cls,
        account_id: str = None,
        auth_session: Session | None = None,
        **kwargs,
    ) -> "Client":
        """
        Create a Client instance from optional identifier and Komodo Platform auth
        session.

        The HTTP session is automatically set.

        :param account_id:
        :param auth_session:
        :param kwargs:
        :return:
        """
        self = Client(account_id, auth_session, **kwargs)
        return await self.__aenter__()

    async def close(self):
        await self.__aexit__(None, None, None)

    async def __aenter__(self) -> "Client":
        return self

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        self._logger.debug(f"Closing Client")
        await asyncio.sleep(0.250)  # https://docs.aiohttp.org/en/stable/client_advanced.html#graceful-shutdown
        await self._client_session.rest_client_async.close()

    @property
    def iam(self) -> "IamApi":
        from komodo.api.iam_api import IamApi

        return IamApi(api_client=self._client_session)

    @staticmethod
    def get_system_info() -> str:
        """
        Get system information including Python version and system architecture.

        Returns:
            str: Formatted string with system information
        """
        python_version = sys.version.split()[0]
        system_name = platform.system()
        machine_arch = platform.machine()

        return f"Python {python_version}; {system_name} {machine_arch}"

    def refresh_api_key_hook(self, configuration):
        """
        Update the configuration's access token by accessing the auth session's
        access_token property and setting the configuration's api_key. The property
        automatically refreshes the token if it is expired.

        Args:
            configuration: The configuration object to update.
        """

        access_token = self._auth_session.access_token
        configuration.access_token = access_token
        configuration.api_key = {"JWT": access_token, "HTTPBearer": access_token, "x-account-id": self.x_account_id}
