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

from .basesdk import BaseSDK
from .httpclient import AsyncHttpClient, HttpClient
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.assets import Assets
from mixpeek.collections import Collections
from mixpeek.feature_extractors import FeatureExtractors
from mixpeek.feature_search import FeatureSearch
from mixpeek.features import Features
from mixpeek.health import Health
from mixpeek.ingest_assets import IngestAssets
from mixpeek.models import internal
from mixpeek.namespaces import Namespaces
from mixpeek.organizations import Organizations
from mixpeek.tasks import Tasks
from mixpeek.taxonomy_entities import TaxonomyEntities
from mixpeek.types import OptionalNullable, UNSET
from typing import Any, Callable, Dict, Optional, Union


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
    namespaces: Namespaces
    features: Features
    feature_search: FeatureSearch
    feature_extractors: FeatureExtractors
    ingest_assets: IngestAssets
    taxonomy_entities: TaxonomyEntities
    assets: Assets
    collections: Collections
    tasks: Tasks

    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
        """
        if client is None:
            client = httpx.Client()

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

        if async_client is None:
            async_client = httpx.AsyncClient()

        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,
                async_client=async_client,
                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, self.sdk_configuration.client
        )
        if current_server_url != server_url:
            self.sdk_configuration.server_url = server_url

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

        self._init_sdks()

    def _init_sdks(self):
        self.health = Health(self.sdk_configuration)
        self.organizations = Organizations(self.sdk_configuration)
        self.namespaces = Namespaces(self.sdk_configuration)
        self.features = Features(self.sdk_configuration)
        self.feature_search = FeatureSearch(self.sdk_configuration)
        self.feature_extractors = FeatureExtractors(self.sdk_configuration)
        self.ingest_assets = IngestAssets(self.sdk_configuration)
        self.taxonomy_entities = TaxonomyEntities(self.sdk_configuration)
        self.assets = Assets(self.sdk_configuration)
        self.collections = Collections(self.sdk_configuration)
        self.tasks = Tasks(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:
            self.sdk_configuration.client.close()

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