# The Okta software accompanied by this notice is provided pursuant to the following terms:
# Copyright © 2025-Present, Okta, Inc.
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
# License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.
# coding: utf-8

"""
    Okta Admin Management

    Allows customers to easily access the Okta Management APIs

    The version of the OpenAPI document: 5.1.0
    Contact: devex-public@okta.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501

import logging
# AUTO-GENERATED! DO NOT EDIT FILE DIRECTLY
# This client class is typically generated based on an API specification (e.g., OpenAPI).
# Changes to this file may be overwritten upon regeneration.
# SEE CONTRIBUTOR DOCUMENTATION
import aiohttp

from okta.api.agent_pools_api import AgentPoolsApi
from okta.api.api_service_integrations_api import ApiServiceIntegrationsApi
from okta.api.api_token_api import ApiTokenApi
from okta.api.application_api import ApplicationApi
from okta.api.application_connections_api import ApplicationConnectionsApi
from okta.api.application_credentials_api import ApplicationCredentialsApi
from okta.api.application_features_api import ApplicationFeaturesApi
from okta.api.application_grants_api import ApplicationGrantsApi
from okta.api.application_groups_api import ApplicationGroupsApi
from okta.api.application_logos_api import ApplicationLogosApi
from okta.api.application_policies_api import ApplicationPoliciesApi
from okta.api.application_sso_api import ApplicationSSOApi
from okta.api.application_tokens_api import ApplicationTokensApi
from okta.api.application_users_api import ApplicationUsersApi
from okta.api.attack_protection_api import AttackProtectionApi
from okta.api.authenticator_api import AuthenticatorApi
from okta.api.authorization_server_api import AuthorizationServerApi
from okta.api.behavior_api import BehaviorApi
from okta.api.captcha_api import CAPTCHAApi
from okta.api.custom_domain_api import CustomDomainApi
from okta.api.customization_api import CustomizationApi
from okta.api.device_api import DeviceApi
from okta.api.device_assurance_api import DeviceAssuranceApi
from okta.api.email_domain_api import EmailDomainApi
from okta.api.email_server_api import EmailServerApi
from okta.api.event_hook_api import EventHookApi
from okta.api.feature_api import FeatureApi
from okta.api.group_api import GroupApi
from okta.api.hook_key_api import HookKeyApi
from okta.api.identity_provider_api import IdentityProviderApi
from okta.api.identity_source_api import IdentitySourceApi
from okta.api.inline_hook_api import InlineHookApi
from okta.api.linked_object_api import LinkedObjectApi
from okta.api.log_stream_api import LogStreamApi
from okta.api.network_zone_api import NetworkZoneApi
from okta.api.org_setting_api import OrgSettingApi
from okta.api.policy_api import PolicyApi
from okta.api.principal_rate_limit_api import PrincipalRateLimitApi
from okta.api.profile_mapping_api import ProfileMappingApi
from okta.api.push_provider_api import PushProviderApi
from okta.api.rate_limit_settings_api import RateLimitSettingsApi
from okta.api.realm_api import RealmApi
from okta.api.resource_set_api import ResourceSetApi
from okta.api.risk_event_api import RiskEventApi
from okta.api.risk_provider_api import RiskProviderApi
from okta.api.role_api import RoleApi
from okta.api.role_assignment_api import RoleAssignmentApi
from okta.api.role_target_api import RoleTargetApi
from okta.api.schema_api import SchemaApi
from okta.api.session_api import SessionApi
from okta.api.subscription_api import SubscriptionApi
from okta.api.system_log_api import SystemLogApi
from okta.api.template_api import TemplateApi
from okta.api.threat_insight_api import ThreatInsightApi
from okta.api.trusted_origin_api import TrustedOriginApi
from okta.api.ui_schema_api import UISchemaApi
from okta.api.user_api import UserApi
from okta.api.user_factor_api import UserFactorApi
from okta.api.user_type_api import UserTypeApi
from okta.cache.no_op_cache import NoOpCache
from okta.cache.okta_cache import OktaCache
from okta.config.config_setter import ConfigSetter
from okta.config.config_validator import ConfigValidator
from okta.logger import setup_logging
from okta.request_executor import RequestExecutor


class Client(
    AgentPoolsApi,
    ApiServiceIntegrationsApi,
    ApiTokenApi,
    ApplicationApi,
    ApplicationConnectionsApi,
    ApplicationCredentialsApi,
    ApplicationFeaturesApi,
    ApplicationGrantsApi,
    ApplicationGroupsApi,
    ApplicationLogosApi,
    ApplicationPoliciesApi,
    ApplicationSSOApi,
    ApplicationTokensApi,
    ApplicationUsersApi,
    AttackProtectionApi,
    AuthenticatorApi,
    AuthorizationServerApi,
    BehaviorApi,
    CAPTCHAApi,
    CustomDomainApi,
    CustomizationApi,
    DeviceApi,
    DeviceAssuranceApi,
    EmailDomainApi,
    EmailServerApi,
    EventHookApi,
    FeatureApi,
    GroupApi,
    HookKeyApi,
    IdentityProviderApi,
    IdentitySourceApi,
    InlineHookApi,
    LinkedObjectApi,
    LogStreamApi,
    NetworkZoneApi,
    OrgSettingApi,
    PolicyApi,
    PrincipalRateLimitApi,
    ProfileMappingApi,
    PushProviderApi,
    RateLimitSettingsApi,
    RealmApi,
    ResourceSetApi,
    RiskEventApi,
    RiskProviderApi,
    RoleApi,
    RoleAssignmentApi,
    RoleTargetApi,
    SchemaApi,
    SessionApi,
    SubscriptionApi,
    SystemLogApi,
    TemplateApi,
    ThreatInsightApi,
    TrustedOriginApi,
    UISchemaApi,
    UserApi,
    UserFactorApi,
    UserTypeApi,

):
    """An Okta client object, serving as an entry point to various Okta APIs."""

    def __init__(self, user_config: dict = {}):
        # Load configuration
        client_config_setter = ConfigSetter()
        client_config_setter._apply_config({'client': user_config})
        self._config = client_config_setter.get_config()
        # Prune configuration to remove unnecessary fields
        self._config = client_config_setter._prune_config(self._config)
        # Validate configuration
        ConfigValidator(self._config)
        # Initialize superclasses (the specific Okta API clients like UserApi, ApplicationApi)
        # These superclasses would typically contain the methods corresponding to API operations.
        super().__init__(configuration=self._config)

        # Set client instance variables from the validated configuration
        self._authorization_mode = self._config["client"]["authorizationMode"]
        self._base_url = self._config["client"]["orgUrl"]  # Base URL for the Okta organization
        self._api_token = self._config["client"].get("token", None)  # For SSWS token authentication
        self._client_id = None  # For OAuth 2.0 / OpenID Connect
        self._scopes = None  # For OAuth 2.0 / OpenID Connect
        self._private_key = None  # For OAuth 2.0 Private Key JWT
        self._oauth_token_renewal_offset = None  # Offset for proactive OAuth token renewal

        # Determine which cache to use (NoOpCache or OktaCache)
        cache = NoOpCache()
        if self._config["client"]["cache"]["enabled"] is True:
            if user_config.get("cacheManager", None) is None:
                time_to_idle = self._config["client"]["cache"]["defaultTti"]
                time_to_live = self._config["client"]["cache"]["defaultTtl"]
                cache = OktaCache(
                    time_to_live,
                    time_to_idle
                )
            else:
                cache = user_config.get("cacheManager")

        # Determine request executor to use
        # The RequestExecutor handles the actual HTTP calls.
        self._request_executor = \
            user_config.get("requestExecutor", RequestExecutor)(
                self._config,
                cache,
                user_config.get("httpClient", None)
            )

        # Set private key variables if using PrivateKey authorization mode (for OAuth 2.0)
        if self._authorization_mode == 'PrivateKey':
            self._client_id = self._config["client"]["clientId"]
            self._scopes = self._config["client"]["scopes"]
            self._private_key = self._config["client"]["privateKey"]
            self._oauth_token_renewal_offset = self._config["client"]["oauthTokenRenewalOffset"]

        # Setup logging for the SDK
        setup_logging(log_level=self._config["client"]["logging"]["logLevel"])
        if self._config["client"]["logging"]["enabled"] is True:
            logger = logging.getLogger('okta-sdk-python')
            logger.disabled = False

    async def __aenter__(self):
        """Automatically create and set session within context manager for async operations."""
        self._session = aiohttp.ClientSession()
        self._request_executor.set_session(self._session)
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """Automatically close session within context manager for async operations."""
        await self._session.close()

    """
    Getters for client properties
    """

    def get_config(self):
        """Returns the client's configuration."""
        return self._config

    def get_scopes(self):
        """Returns the OAuth scopes if configured."""
        return self._scopes

    def get_base_url(self):
        """Returns the base URL for the Okta organization."""
        return self._base_url

    def get_request_executor(self):
        """Returns the request executor instance."""
        return self._request_executor

    """
    Custom Header Management
    """

    def set_custom_headers(self, headers: dict):
        """Sets custom headers to be sent with every request."""
        self._request_executor.set_custom_headers(headers)

    def clear_custom_headers(self):
        """Clears any previously set custom headers."""
        self._request_executor.clear_custom_headers()

    def get_custom_headers(self) -> dict:
        """Gets the currently set custom headers."""
        return self._request_executor.get_custom_headers()

    def get_default_headers(self) -> dict:
        """Gets the default headers used by the request executor."""
        return self._request_executor.get_default_headers()
