"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from .httpclient import AsyncHttpClient, ClientOwner, HttpClient, close_clients
from .sdkconfiguration import SDKConfiguration
from .utils.logger import Logger, get_default_logger
from .utils.retries import RetryConfig
import httpx
from mixpeek import models, utils
from mixpeek._hooks import SDKHooks
from mixpeek.bucketobjects import BucketObjects
from mixpeek.buckets import Buckets
from mixpeek.clusters import Clusters
from mixpeek.collectioncache import CollectionCache
from mixpeek.collectiondocuments import CollectionDocuments
from mixpeek.collections import Collections
from mixpeek.features import Features
from mixpeek.health import Health
from mixpeek.models import internal
from mixpeek.namespaces import Namespaces
from mixpeek.organizationnotifications import OrganizationNotifications
from mixpeek.organizations import Organizations
from mixpeek.organizationsusage import OrganizationsUsage
from mixpeek.research import Research
from mixpeek.retrieverinteractions import RetrieverInteractions
from mixpeek.retrievers import Retrievers
from mixpeek.retrieverstages import RetrieverStages
from mixpeek.tasks import Tasks
from mixpeek.taxonomies import Taxonomies
from mixpeek.types import OptionalNullable, UNSET
from mixpeek.users import Users
from typing import Any, Callable, Dict, Optional, Union, cast
import weakref


class Mixpeek(BaseSDK):
    r"""Mixpeek API: This is the Mixpeek API, providing access to various endpoints for data processing and retrieval."""

    health: Health
    organizations: Organizations
    users: Users
    organizations_usage: OrganizationsUsage
    organization_notifications: OrganizationNotifications
    namespaces: Namespaces
    buckets: Buckets
    bucket_objects: BucketObjects
    collections: Collections
    collection_cache: CollectionCache
    collection_documents: CollectionDocuments
    features: Features
    retrievers: Retrievers
    retriever_stages: RetrieverStages
    retriever_interactions: RetrieverInteractions
    tasks: Tasks
    research: Research
    taxonomies: Taxonomies
    clusters: Clusters

    def __init__(
        self,
        token: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None,
        x_namespace: Optional[str] = None,
        server_idx: Optional[int] = None,
        server_url: Optional[str] = None,
        url_params: Optional[Dict[str, str]] = None,
        client: Optional[HttpClient] = None,
        async_client: Optional[AsyncHttpClient] = None,
        retry_config: OptionalNullable[RetryConfig] = UNSET,
        timeout_ms: Optional[int] = None,
        debug_logger: Optional[Logger] = None,
    ) -> None:
        r"""Instantiates the SDK configuring it with the provided parameters.

        :param token: The token required for authentication
        :param x_namespace: Configures the x_namespace parameter for all supported operations
        :param server_idx: The index of the server to use for all methods
        :param server_url: The server URL to use for all methods
        :param url_params: Parameters to optionally template the server URL with
        :param client: The HTTP client to use for all synchronous methods
        :param async_client: The Async HTTP client to use for all asynchronous methods
        :param retry_config: The retry configuration to use for all supported methods
        :param timeout_ms: Optional request timeout applied to each operation in milliseconds
        """
        client_supplied = True
        if client is None:
            client = httpx.Client()
            client_supplied = False

        assert issubclass(
            type(client), HttpClient
        ), "The provided client must implement the HttpClient protocol."

        async_client_supplied = True
        if async_client is None:
            async_client = httpx.AsyncClient()
            async_client_supplied = False

        if debug_logger is None:
            debug_logger = get_default_logger()

        assert issubclass(
            type(async_client), AsyncHttpClient
        ), "The provided async_client must implement the AsyncHttpClient protocol."

        security: Any = None
        if callable(token):
            # pylint: disable=unnecessary-lambda-assignment
            security = lambda: models.Security(token=token())
        else:
            security = models.Security(token=token)

        if server_url is not None:
            if url_params is not None:
                server_url = utils.template_url(server_url, url_params)

        _globals = internal.Globals(
            x_namespace=utils.get_global_from_env(
                x_namespace, "MIXPEEK_X_NAMESPACE", str
            ),
        )

        BaseSDK.__init__(
            self,
            SDKConfiguration(
                client=client,
                client_supplied=client_supplied,
                async_client=async_client,
                async_client_supplied=async_client_supplied,
                globals=_globals,
                security=security,
                server_url=server_url,
                server_idx=server_idx,
                retry_config=retry_config,
                timeout_ms=timeout_ms,
                debug_logger=debug_logger,
            ),
        )

        hooks = SDKHooks()

        current_server_url, *_ = self.sdk_configuration.get_server_details()
        server_url, self.sdk_configuration.client = hooks.sdk_init(
            current_server_url, client
        )
        if current_server_url != server_url:
            self.sdk_configuration.server_url = server_url

        # pylint: disable=protected-access
        self.sdk_configuration.__dict__["_hooks"] = hooks

        weakref.finalize(
            self,
            close_clients,
            cast(ClientOwner, self.sdk_configuration),
            self.sdk_configuration.client,
            self.sdk_configuration.client_supplied,
            self.sdk_configuration.async_client,
            self.sdk_configuration.async_client_supplied,
        )

        self._init_sdks()

    def _init_sdks(self):
        self.health = Health(self.sdk_configuration)
        self.organizations = Organizations(self.sdk_configuration)
        self.users = Users(self.sdk_configuration)
        self.organizations_usage = OrganizationsUsage(self.sdk_configuration)
        self.organization_notifications = OrganizationNotifications(
            self.sdk_configuration
        )
        self.namespaces = Namespaces(self.sdk_configuration)
        self.buckets = Buckets(self.sdk_configuration)
        self.bucket_objects = BucketObjects(self.sdk_configuration)
        self.collections = Collections(self.sdk_configuration)
        self.collection_cache = CollectionCache(self.sdk_configuration)
        self.collection_documents = CollectionDocuments(self.sdk_configuration)
        self.features = Features(self.sdk_configuration)
        self.retrievers = Retrievers(self.sdk_configuration)
        self.retriever_stages = RetrieverStages(self.sdk_configuration)
        self.retriever_interactions = RetrieverInteractions(self.sdk_configuration)
        self.tasks = Tasks(self.sdk_configuration)
        self.research = Research(self.sdk_configuration)
        self.taxonomies = Taxonomies(self.sdk_configuration)
        self.clusters = Clusters(self.sdk_configuration)

    def __enter__(self):
        return self

    async def __aenter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if (
            self.sdk_configuration.client is not None
            and not self.sdk_configuration.client_supplied
        ):
            self.sdk_configuration.client.close()
        self.sdk_configuration.client = None

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if (
            self.sdk_configuration.async_client is not None
            and not self.sdk_configuration.async_client_supplied
        ):
            await self.sdk_configuration.async_client.aclose()
        self.sdk_configuration.async_client = None
