# @generated
# This file was automatically generated by the ncae-sdk code generator.
# DO NOT EDIT MANUALLY, ANY CHANGES WILL BE OVERWRITTEN.

import os
from functools import cached_property
from types import TracebackType
from typing import Optional, Type

from httpx import BaseTransport
from typing_extensions import Self

from ncae_sdk._auth import Auth, SessionAuth
from ncae_sdk._session import SessionContext
from ncae_sdk._sync.session import Session
from ncae_sdk._util import parse_env_bool, parse_env_int
from ncae_sdk.endpoints import (
    AuditLogEndpoint,
    AwxModuleEndpoint,
    BasePhaseEndpoint,
    ChangeScheduleEndpoint,
    ChangeScheduleRunEndpoint,
    CmdbEntryEndpoint,
    CredentialEndpoint,
    DeviceEndpoint,
    DeviceGroupEndpoint,
    DeviceModelEndpoint,
    ExtApiAuthEndpoint,
    ExtApiPhaseEndpoint,
    ExtApiServiceEndpoint,
    GrafanaDashboardEndpoint,
    GrafanaSystemEndpoint,
    InfluxRepositoryEndpoint,
    InfluxSystemEndpoint,
    ModuleEndpoint,
    PhaseEndpoint,
    PhaseInstanceEndpoint,
    PollingPhaseEndpoint,
    PythonScriptPhaseEndpoint,
    ServiceEndpoint,
    ServiceInstanceEndpoint,
    ServiceInstanceLogEndpoint,
    ServiceManagementPhaseEndpoint,
    SharedDataBucketEndpoint,
    SharedDataSubscriberEndpoint,
    TagEndpoint,
    TagRelationEndpoint,
    TenantEndpoint,
    TransactionEndpoint,
    UploadFileEndpoint,
    UsageLogEndpoint,
    UserEndpoint,
)
from ncae_sdk.endpoints._sync.favourite import FavouriteEndpoint
from ncae_sdk.endpoints._sync.report import ReportEndpoint


class Client:
    def __init__(
        self,
        base_url: Optional[str] = None,
        auth: Optional[Auth] = None,
        timeout: Optional[int] = None,
        verify: Optional[bool] = None,
        httpx_transport: Optional[BaseTransport] = None,
    ) -> None:
        """
        Initializes a new asynchronous client for interacting with the NCAE API.

        This client provides access to various endpoints such as audit logs, devices, credentials, and more. It is
        based on an underlying session that uses httpx for asynchronous HTTP requests. For these reasons, it is
        recommended to use this client as a context manager, as this ensures cleanup and allows proper pooling.

        All arguments are marked as optional, which will fallback to environment variables or default values.
        If no suitable configuration is found, an error will be raised during instantiation.

        :param base_url: The base URL of the NCAE API, e.g. `https://ncae.example.com/api/`.
        :param auth: An instance of :class:`Auth` that provides authentication for the API requests.
        :param timeout: The desired timeout for API requests in seconds. Usage of default value is recommended.
        :param verify: Whether to verify SSL certificates. Set to `False` if you are using a self-signed certificate.
        """
        if not base_url:
            base_url = os.environ.get("NCAE_SDK_BASE_URL")
            if not base_url:
                raise ValueError("Unable to determine NCAE SDK base URL.")

        if not auth:
            username = os.environ.get("NCAE_SDK_USERNAME")
            password = os.environ.get("NCAE_SDK_PASSWORD")
            if not username or not password:
                raise ValueError("Unable to determine NCAE SDK authentication credentials.")

            auth = SessionAuth(username=username, password=password)

        if timeout is None:
            if value := os.environ.get("NCAE_SDK_HTTP_TIMEOUT"):
                timeout = parse_env_int(value)
            else:
                timeout = 5

        if verify is None:
            if value := os.environ.get("NCAE_SDK_HTTP_VERIFY"):
                verify = parse_env_bool(value)
            else:
                verify = True

        self._session: Session = Session.create(
            base_url=base_url,
            auth=auth,
            timeout=timeout,
            verify=verify,
            httpx_transport=httpx_transport,
        )

    def clone_with_context(self, context: SessionContext) -> Self:
        instance = self.__class__.__new__(self.__class__)
        instance._session = self._session.clone(context)
        return instance

    def close(self) -> None:
        self._session.close()

    def __enter__(self) -> Self:
        return self

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        self.close()

    def ping(self) -> None:
        self._session.get("readyz")

    @property
    def session(self) -> Session:
        return self._session

    @cached_property
    def audit_logs(self) -> AuditLogEndpoint:
        return AuditLogEndpoint(session=self._session)

    @cached_property
    def awx_modules(self) -> AwxModuleEndpoint:
        return AwxModuleEndpoint(session=self._session)

    @cached_property
    def base_phases(self) -> BasePhaseEndpoint:
        return BasePhaseEndpoint(session=self._session)

    @cached_property
    def change_schedules(self) -> ChangeScheduleEndpoint:
        return ChangeScheduleEndpoint(session=self._session)

    @cached_property
    def change_schedule_runs(self) -> ChangeScheduleRunEndpoint:
        return ChangeScheduleRunEndpoint(session=self._session)

    @cached_property
    def cmdb_entries(self) -> CmdbEntryEndpoint:
        return CmdbEntryEndpoint(session=self._session)

    @cached_property
    def credentials(self) -> CredentialEndpoint:
        return CredentialEndpoint(session=self._session)

    @cached_property
    def devices(self) -> DeviceEndpoint:
        return DeviceEndpoint(session=self._session)

    @cached_property
    def device_groups(self) -> DeviceGroupEndpoint:
        return DeviceGroupEndpoint(session=self._session)

    @cached_property
    def device_models(self) -> DeviceModelEndpoint:
        return DeviceModelEndpoint(session=self._session)

    @cached_property
    def ext_api_auths(self) -> ExtApiAuthEndpoint:
        return ExtApiAuthEndpoint(session=self._session)

    @cached_property
    def ext_api_services(self) -> ExtApiServiceEndpoint:
        return ExtApiServiceEndpoint(session=self._session)

    @cached_property
    def ext_api_phases(self) -> ExtApiPhaseEndpoint:
        return ExtApiPhaseEndpoint(session=self._session)

    @cached_property
    def favourites(self) -> FavouriteEndpoint:
        return FavouriteEndpoint(session=self._session)

    @cached_property
    def grafana_dashboards(self) -> GrafanaDashboardEndpoint:
        return GrafanaDashboardEndpoint(session=self._session)

    @cached_property
    def grafana_systems(self) -> GrafanaSystemEndpoint:  # noqa: F821
        return GrafanaSystemEndpoint(session=self._session)

    @cached_property
    def influx_repositories(self) -> InfluxRepositoryEndpoint:
        return InfluxRepositoryEndpoint(session=self._session)

    @cached_property
    def influx_systems(self) -> InfluxSystemEndpoint:
        return InfluxSystemEndpoint(session=self._session)

    @cached_property
    def modules(self) -> ModuleEndpoint:
        return ModuleEndpoint(session=self._session)

    @cached_property
    def phases(self) -> PhaseEndpoint:
        return PhaseEndpoint(session=self._session)

    @cached_property
    def phase_instances(self) -> PhaseInstanceEndpoint:
        return PhaseInstanceEndpoint(session=self._session)

    @cached_property
    def polling_phases(self) -> PollingPhaseEndpoint:
        return PollingPhaseEndpoint(session=self._session)

    @cached_property
    def python_script_phases(self) -> PythonScriptPhaseEndpoint:
        return PythonScriptPhaseEndpoint(session=self._session)

    @cached_property
    def reports(self) -> ReportEndpoint:
        return ReportEndpoint(session=self._session)

    @cached_property
    def services(self) -> ServiceEndpoint:
        return ServiceEndpoint(session=self._session)

    @cached_property
    def service_instances(self) -> ServiceInstanceEndpoint:
        return ServiceInstanceEndpoint(session=self._session)

    @cached_property
    def service_instance_logs(self) -> ServiceInstanceLogEndpoint:
        return ServiceInstanceLogEndpoint(session=self._session)

    @cached_property
    def shared_data_buckets(self) -> SharedDataBucketEndpoint:
        return SharedDataBucketEndpoint(session=self._session)

    @cached_property
    def shared_data_subscribers(self) -> SharedDataSubscriberEndpoint:
        return SharedDataSubscriberEndpoint(session=self._session)

    @cached_property
    def service_management_phases(self) -> ServiceManagementPhaseEndpoint:
        return ServiceManagementPhaseEndpoint(session=self._session)

    @cached_property
    def tags(self) -> TagEndpoint:
        return TagEndpoint(session=self._session)

    @cached_property
    def tag_relations(self) -> TagRelationEndpoint:
        return TagRelationEndpoint(session=self._session)

    @cached_property
    def tenants(self) -> TenantEndpoint:
        return TenantEndpoint(session=self._session)

    @cached_property
    def transactions(self) -> TransactionEndpoint:
        return TransactionEndpoint(session=self._session)

    @cached_property
    def upload_files(self) -> UploadFileEndpoint:
        return UploadFileEndpoint(session=self._session)

    @cached_property
    def usage_logs(self) -> UsageLogEndpoint:
        return UsageLogEndpoint(session=self._session)

    @cached_property
    def users(self) -> UserEndpoint:
        return UserEndpoint(session=self._session)
