"""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
from gsmservice_gateway import models, utils
from gsmservice_gateway._hooks import SDKHooks
from gsmservice_gateway.accounts import Accounts
from gsmservice_gateway.common import Common
from gsmservice_gateway.incoming import Incoming
from gsmservice_gateway.outgoing import Outgoing
from gsmservice_gateway.senders import Senders
from gsmservice_gateway.types import OptionalNullable, UNSET
import httpx
from typing import Any, Callable, Dict, Optional, Union


class Client(BaseSDK):
    r"""Messaging Gateway GSMService.pl:
    # Introduction

    This document was created to explain the process of integration any application or system with the **GSMService.pl** SMS Gateway via the *REST API*. Currently, there are several ways to send messages with the GSMService.pl platform:

    * Directly from the [https://bramka.gsmservice.pl](https://bramka.gsmservice.pl) website [User Panel](https://panel.gsmservice.pl)
    * Via this *REST API* and provided *SDKs*
    * Via the legacy (deprecated) versions API: *Webservices (SOAP)* and *HTTP*
    * Via the *MAIL2SMS* service

    This document describes the possibilities offered by **REST API**.

    > **We kindly ask you to read this documentation carefully before starting the integration. This will make the whole process easier and will help you avoid many problems.**

    ## Documentation and Try Outs

    This documentation is available in two formats: [**REDOC**](https://api.gsmservice.pl/rest/) and [**SWAGGER**](https://api.gsmservice.pl/rest/swagger). You can test any endpoint directly from documentation using **Try Out** feature of Swagger. Also you can [download a **YAML** file](https://api.gsmservice.pl/rest/swagger/messaging.yaml) with doc in OpenApi 3.0 format.

    ## Account signup and setup

    Firstly, it is necessary to create your personal account at the GSMService.pl SMS Gateway platform if you haven't one and activate access to the API. To register a new account please [signup the form](https://panel.gsmservice.pl/rejestracja). After signing up and fully activation of an account you have to activate an access to the API.

    To do it please use [this site](https://panel.gsmservice.pl/api) - fill the *New API Access* form with your preferred API login, set your API password, select which API standard you want to activate for this account (select **REST API** there). Optionally you can add IP adresses (or IP pool with CIDR notation) from which access to your API account will be possible. You can also set a callback address there to collect any messages status updates automatically. When a status of a messaga changes, the callback address will be called with passing parameters with new message status.

    After setup an API access you will get an unique **API Access Token** - please write it down as there won't be possible to display it again (you will have the possibility to regenerate it only). This token will be required to authenticate all the requests made with API on your account.

    ## Authentication of API requests

    All the endpoints of this REST API have to be authenticated using your API Access Token with one exception: */rest/ping* endpoint which doesn't need an authentication.

    To make an authenticated request you should add to all requests an ***Authorization* header** which you have generated in previous step:

    ```
    Authorization: Bearer &lt;YOUR_API_ACCESS_TOKEN&gt;
    ```

    ## URLs to connect to API

    Please use this SSL secured adresses to connect to REST API:

    * ```https://api.gsmservice.pl/rest``` - for production system

    * ```https://api.gsmservice.pl/rest-sandbox``` - for test system (Sandbox)

    > [!NOTE]
    > **When calling our API, make sure you are using TLS version 1.2 or higher. Older versions are no longer supported.**

    # SDK Client Libraries

    For developers integrating SMS functionality into their app, we provide a convenient SDK Libraries.

    Our SDKs allow you to quickly start interacting with the Gateway using your favorite programming language. Currently we support the following languages:

    ## PHP 8

    To install PHP SDK issue the following command:

    ```shell
    composer require gsmservice-pl/messaging-sdk-php
    ```
    More information and documentation you can find at our [GitHub](https://github.com/gsmservice-pl/messaging-sdk-php)

    ## Typescript

    To install Typescript SDK issue the following command:

    ### NPM

    ```shell
    npm add @gsmservice-pl/messaging-sdk-typescript
    ```

    More information and documentation you can find at our [GitHub](https://github.com/gsmservice-pl/messaging-sdk-typescript)


    """

    accounts: Accounts
    outgoing: Outgoing
    incoming: Incoming
    common: Common
    r"""This section describes other usefull operations and tools"""
    senders: Senders

    def __init__(
        self,
        bearer: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None,
        server: Optional[str] = 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 bearer: The bearer required for authentication
        :param server: The server by name 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(bearer):
            security = lambda: models.Security(bearer=bearer())  # pylint: disable=unnecessary-lambda-assignment
        else:
            security = models.Security(bearer=bearer)

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

        BaseSDK.__init__(
            self,
            SDKConfiguration(
                client=client,
                async_client=async_client,
                security=security,
                server_url=server_url,
                server=server,
                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.accounts = Accounts(self.sdk_configuration)
        self.outgoing = Outgoing(self.sdk_configuration)
        self.incoming = Incoming(self.sdk_configuration)
        self.common = Common(self.sdk_configuration)
        self.senders = Senders(self.sdk_configuration)
