"""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 neuralseek import models, utils
from neuralseek._hooks import SDKHooks
from neuralseek.analytics import Analytics
from neuralseek.answerratings import AnswerRatings
from neuralseek.categorize import Categorize
from neuralseek.extractentities import ExtractEntities
from neuralseek.findpii import FindPII
from neuralseek.identifylanguage import IdentifyLanguage
from neuralseek.identifylanguagejson import IdentifyLanguageJSON
from neuralseek.keycheck import KeyCheck
from neuralseek.logs import Logs
from neuralseek.maistro import Maistro
from neuralseek.onetimepassword import OneTimePassword
from neuralseek.rate import Rate
from neuralseek.score import Score
from neuralseek.seek_sdk import SeekSDK
from neuralseek.servicetest import ServiceTest
from neuralseek.testquestions import TestQuestions
from neuralseek.testresults import TestResults
from neuralseek.train import Train
from neuralseek.translate import Translate
from neuralseek.translationglossary import TranslationGlossary
from neuralseek.types import OptionalNullable, UNSET
from neuralseek.userdata import UserData
from typing import Any, Callable, Dict, List, Optional, Union, cast
import weakref


class Neuralseek(BaseSDK):
    r"""NeuralSeek: NeuralSeek - The business LLM accelerator
    https://documentation.neuralseek.com - Documentation
    """

    seek: SeekSDK
    categorize: Categorize
    maistro: Maistro
    extract_entities: ExtractEntities
    translate: Translate
    translation_glossary: TranslationGlossary
    identify_language: IdentifyLanguage
    identify_language_json: IdentifyLanguageJSON
    find_pii: FindPII
    rate: Rate
    answer_ratings: AnswerRatings
    score: Score
    train: Train
    service_test: ServiceTest
    test_questions: TestQuestions
    test_results: TestResults
    analytics: Analytics
    logs: Logs
    one_time_password: OneTimePassword
    user_data: UserData
    key_check: KeyCheck

    def __init__(
        self,
        api_key: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None,
        instance: 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 api_key: The api_key required for authentication
        :param instance: Allows setting the instance variable for url substitution
        :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(api_key):
            # pylint: disable=unnecessary-lambda-assignment
            security = lambda: models.Security(api_key=api_key())
        else:
            security = models.Security(api_key=api_key)

        if server_url is not None:
            if url_params is not None:
                server_url = utils.template_url(server_url, url_params)
        server_defaults: List[Dict[str, str]] = [
            {
                "instance": instance or "demo",
            },
        ]

        BaseSDK.__init__(
            self,
            SDKConfiguration(
                client=client,
                async_client=async_client,
                security=security,
                server_url=server_url,
                server_idx=server_idx,
                server_defaults=server_defaults,
                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

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

        self._init_sdks()

    def _init_sdks(self):
        self.seek = SeekSDK(self.sdk_configuration)
        self.categorize = Categorize(self.sdk_configuration)
        self.maistro = Maistro(self.sdk_configuration)
        self.extract_entities = ExtractEntities(self.sdk_configuration)
        self.translate = Translate(self.sdk_configuration)
        self.translation_glossary = TranslationGlossary(self.sdk_configuration)
        self.identify_language = IdentifyLanguage(self.sdk_configuration)
        self.identify_language_json = IdentifyLanguageJSON(self.sdk_configuration)
        self.find_pii = FindPII(self.sdk_configuration)
        self.rate = Rate(self.sdk_configuration)
        self.answer_ratings = AnswerRatings(self.sdk_configuration)
        self.score = Score(self.sdk_configuration)
        self.train = Train(self.sdk_configuration)
        self.service_test = ServiceTest(self.sdk_configuration)
        self.test_questions = TestQuestions(self.sdk_configuration)
        self.test_results = TestResults(self.sdk_configuration)
        self.analytics = Analytics(self.sdk_configuration)
        self.logs = Logs(self.sdk_configuration)
        self.one_time_password = OneTimePassword(self.sdk_configuration)
        self.user_data = UserData(self.sdk_configuration)
        self.key_check = KeyCheck(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()
