## 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

import httpx

from komodo.auth.Session import Session

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

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:
        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}
