"""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
import importlib
from squadcast_sdk import models, utils
from squadcast_sdk._hooks import SDKHooks
from squadcast_sdk.types import OptionalNullable, UNSET
import sys
from typing import Any, Callable, Dict, Optional, TYPE_CHECKING, Union, cast
import weakref

if TYPE_CHECKING:
    from squadcast_sdk.additionalresponders import AdditionalResponders
    from squadcast_sdk.analytics import Analytics
    from squadcast_sdk.auditlogs import AuditLogs
    from squadcast_sdk.communicationcards import CommunicationCards
    from squadcast_sdk.componentgroups import ComponentGroups
    from squadcast_sdk.components import Components
    from squadcast_sdk.dedupkeys import DedupKeys
    from squadcast_sdk.escalationpolicies_sdk import EscalationPoliciesSDK
    from squadcast_sdk.exports import Exports
    from squadcast_sdk.exportschedule import ExportSchedule
    from squadcast_sdk.extensions import Extensions
    from squadcast_sdk.globaleventrules import GlobalEventRules
    from squadcast_sdk.globaloncallreminderrules_sdk import GlobalOncallReminderRulesSDK
    from squadcast_sdk.incidents import Incidents
    from squadcast_sdk.issues import Issues
    from squadcast_sdk.maintenances import Maintenances
    from squadcast_sdk.overlays import Overlays
    from squadcast_sdk.overrides import Overrides
    from squadcast_sdk.postmortems_sdk import PostmortemsSDK
    from squadcast_sdk.rotations import Rotations
    from squadcast_sdk.rules import Rules
    from squadcast_sdk.rulesets import Rulesets
    from squadcast_sdk.runbooks_sdk import RunbooksSDK
    from squadcast_sdk.schedules_sdk import SchedulesSDK
    from squadcast_sdk.services_sdk import ServicesSDK
    from squadcast_sdk.slos_sdk import SlosSDK
    from squadcast_sdk.snoozenotifications import SnoozeNotifications
    from squadcast_sdk.squads_sdk import SquadsSDK
    from squadcast_sdk.squadsv4 import SquadsV4
    from squadcast_sdk.statuspages_sdk_1 import StatusPagesSDK1
    from squadcast_sdk.statuspages_sdk_2 import StatuspagesSDK2
    from squadcast_sdk.subscribers import Subscribers
    from squadcast_sdk.teams import Teams
    from squadcast_sdk.users import Users
    from squadcast_sdk.webforms_sdk import WebformsSDK
    from squadcast_sdk.webhooks import Webhooks
    from squadcast_sdk.workflows_sdk import WorkflowsSDK


class SquadcastSDK(BaseSDK):
    analytics: "Analytics"
    audit_logs: "AuditLogs"
    escalation_policies: "EscalationPoliciesSDK"
    exports: "Exports"
    extensions: "Extensions"
    webhooks: "Webhooks"
    incidents: "Incidents"
    global_event_rules: "GlobalEventRules"
    rulesets: "Rulesets"
    rules: "Rules"
    global_oncall_reminder_rules: "GlobalOncallReminderRulesSDK"
    postmortems: "PostmortemsSDK"
    communication_cards: "CommunicationCards"
    runbooks: "RunbooksSDK"
    additional_responders: "AdditionalResponders"
    snooze_notifications: "SnoozeNotifications"
    users: "Users"
    services: "ServicesSDK"
    dedup_keys: "DedupKeys"
    overlays: "Overlays"
    slos: "SlosSDK"
    teams: "Teams"
    webforms: "WebformsSDK"
    workflows: "WorkflowsSDK"
    schedules: "SchedulesSDK"
    export_schedule: "ExportSchedule"
    overrides: "Overrides"
    rotations: "Rotations"
    squads: "SquadsSDK"
    squads_v4: "SquadsV4"
    status_pages: "StatusPagesSDK1"
    components: "Components"
    component_groups: "ComponentGroups"
    issues: "Issues"
    maintenances: "Maintenances"
    statuspages: "StatuspagesSDK2"
    subscribers: "Subscribers"
    _sub_sdk_map = {
        "analytics": ("squadcast_sdk.analytics", "Analytics"),
        "audit_logs": ("squadcast_sdk.auditlogs", "AuditLogs"),
        "escalation_policies": (
            "squadcast_sdk.escalationpolicies_sdk",
            "EscalationPoliciesSDK",
        ),
        "exports": ("squadcast_sdk.exports", "Exports"),
        "extensions": ("squadcast_sdk.extensions", "Extensions"),
        "webhooks": ("squadcast_sdk.webhooks", "Webhooks"),
        "incidents": ("squadcast_sdk.incidents", "Incidents"),
        "global_event_rules": ("squadcast_sdk.globaleventrules", "GlobalEventRules"),
        "rulesets": ("squadcast_sdk.rulesets", "Rulesets"),
        "rules": ("squadcast_sdk.rules", "Rules"),
        "global_oncall_reminder_rules": (
            "squadcast_sdk.globaloncallreminderrules_sdk",
            "GlobalOncallReminderRulesSDK",
        ),
        "postmortems": ("squadcast_sdk.postmortems_sdk", "PostmortemsSDK"),
        "communication_cards": (
            "squadcast_sdk.communicationcards",
            "CommunicationCards",
        ),
        "runbooks": ("squadcast_sdk.runbooks_sdk", "RunbooksSDK"),
        "additional_responders": (
            "squadcast_sdk.additionalresponders",
            "AdditionalResponders",
        ),
        "snooze_notifications": (
            "squadcast_sdk.snoozenotifications",
            "SnoozeNotifications",
        ),
        "users": ("squadcast_sdk.users", "Users"),
        "services": ("squadcast_sdk.services_sdk", "ServicesSDK"),
        "dedup_keys": ("squadcast_sdk.dedupkeys", "DedupKeys"),
        "overlays": ("squadcast_sdk.overlays", "Overlays"),
        "slos": ("squadcast_sdk.slos_sdk", "SlosSDK"),
        "teams": ("squadcast_sdk.teams", "Teams"),
        "webforms": ("squadcast_sdk.webforms_sdk", "WebformsSDK"),
        "workflows": ("squadcast_sdk.workflows_sdk", "WorkflowsSDK"),
        "schedules": ("squadcast_sdk.schedules_sdk", "SchedulesSDK"),
        "export_schedule": ("squadcast_sdk.exportschedule", "ExportSchedule"),
        "overrides": ("squadcast_sdk.overrides", "Overrides"),
        "rotations": ("squadcast_sdk.rotations", "Rotations"),
        "squads": ("squadcast_sdk.squads_sdk", "SquadsSDK"),
        "squads_v4": ("squadcast_sdk.squadsv4", "SquadsV4"),
        "status_pages": ("squadcast_sdk.statuspages_sdk_1", "StatusPagesSDK1"),
        "components": ("squadcast_sdk.components", "Components"),
        "component_groups": ("squadcast_sdk.componentgroups", "ComponentGroups"),
        "issues": ("squadcast_sdk.issues", "Issues"),
        "maintenances": ("squadcast_sdk.maintenances", "Maintenances"),
        "statuspages": ("squadcast_sdk.statuspages_sdk_2", "StatuspagesSDK2"),
        "subscribers": ("squadcast_sdk.subscribers", "Subscribers"),
    }

    def __init__(
        self,
        bearer_auth: Union[str, Callable[[], str]],
        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 bearer_auth: The bearer_auth required for authentication
        :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(follow_redirects=True)
            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(follow_redirects=True)
            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(bearer_auth):
            # pylint: disable=unnecessary-lambda-assignment
            security = lambda: models.Security(bearer_auth=bearer_auth())
        else:
            security = models.Security(bearer_auth=bearer_auth)

        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,
                client_supplied=client_supplied,
                async_client=async_client,
                async_client_supplied=async_client_supplied,
                security=security,
                server_url=server_url,
                server_idx=server_idx,
                retry_config=retry_config,
                timeout_ms=timeout_ms,
                debug_logger=debug_logger,
            ),
            parent_ref=self,
        )

        hooks = SDKHooks()

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

        self.sdk_configuration = hooks.sdk_init(self.sdk_configuration)

        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,
        )

    def dynamic_import(self, modname, retries=3):
        for attempt in range(retries):
            try:
                return importlib.import_module(modname)
            except KeyError:
                # Clear any half-initialized module and retry
                sys.modules.pop(modname, None)
                if attempt == retries - 1:
                    break
        raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")

    def __getattr__(self, name: str):
        if name in self._sub_sdk_map:
            module_path, class_name = self._sub_sdk_map[name]
            try:
                module = self.dynamic_import(module_path)
                klass = getattr(module, class_name)
                instance = klass(self.sdk_configuration, parent_ref=self)
                setattr(self, name, instance)
                return instance
            except ImportError as e:
                raise AttributeError(
                    f"Failed to import module {module_path} for attribute {name}: {e}"
                ) from e
            except AttributeError as e:
                raise AttributeError(
                    f"Failed to find class {class_name} in module {module_path} for attribute {name}: {e}"
                ) from e

        raise AttributeError(
            f"'{type(self).__name__}' object has no attribute '{name}'"
        )

    def __dir__(self):
        default_attrs = list(super().__dir__())
        lazy_attrs = list(self._sub_sdk_map.keys())
        return sorted(list(set(default_attrs + lazy_attrs)))

    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
