# 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

from __future__ import annotations

import json
import pprint
import re  # noqa: F401
from typing import Any, ClassVar, Dict, List
from typing import Optional, Set

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from typing_extensions import Annotated
from typing_extensions import Self

from okta.models.application_type import ApplicationType
from okta.models.endpoint_auth_method import EndpointAuthMethod
from okta.models.grant_type import GrantType
from okta.models.response_type import ResponseType
from okta.models.signing_algorithm import SigningAlgorithm


class Client(BaseModel):
    """
    Client
    """  # noqa: E501

    application_type: Optional[ApplicationType] = None
    client_id: Optional[StrictStr] = Field(
        default=None,
        description="Unique key for the client application. The `client_id` is immutable. When you create a client "
        "Application, you can't specify the `client_id` because Okta uses the application ID for the `client_id`.",
    )
    client_id_issued_at: Optional[StrictInt] = Field(
        default=None,
        description="Time at which the `client_id` was issued (measured in unix seconds)",
    )
    client_name: Optional[StrictStr] = Field(
        default=None, description="Human-readable string name of the client application"
    )
    client_secret: Optional[StrictStr] = Field(
        default=None,
        description="OAuth 2.0 client secret string (used for confidential clients). The `client_secret` is shown only on "
        "the response of the creation or update of a client Application (and only if the "
        "`token_endpoint_auth_method` is one that requires a client secret). You can't specify the "
        "`client_secret`. If the `token_endpoint_auth_method` requires one, Okta generates a random "
        "`client_secret` for the client Application.",
    )
    client_secret_expires_at: Optional[Annotated[int, Field(strict=True, ge=0)]] = (
        Field(
            default=None,
            description="Time at which the `client_secret` expires or 0 if it doesn't expire (measured in unix seconds)",
        )
    )
    frontchannel_logout_session_required: Optional[StrictBool] = Field(
        default=None, description="Include user session details"
    )
    frontchannel_logout_uri: Optional[StrictStr] = Field(
        default=None, description="URL where Okta sends the logout request"
    )
    grant_types: Optional[List[GrantType]] = Field(
        default=None,
        description="Array of OAuth 2.0 grant type strings. Default value: `[authorization_code]`",
    )
    initiate_login_uri: Optional[StrictStr] = Field(
        default=None,
        description="URL that a third party can use to initiate a login by the client",
    )
    jwks_uri: Optional[StrictStr] = Field(
        default=None,
        description="URL string that references a [JSON Web Key Set](https://tools.ietf.org/html/rfc7517#section-5) for "
        "validating JWTs presented to Okta",
    )
    logo_uri: Optional[StrictStr] = Field(
        default=None,
        description="URL string that references a logo for the client consent dialog (not the sign-in dialog)",
    )
    policy_uri: Optional[StrictStr] = Field(
        default=None,
        description="URL string of a web page providing the client's policy document",
    )
    post_logout_redirect_uris: Optional[List[StrictStr]] = Field(
        default=None,
        description="Array of redirection URI strings for use for relying party initiated logouts",
    )
    redirect_uris: Optional[List[StrictStr]] = Field(
        default=None,
        description="Array of redirection URI strings for use in redirect-based flows. All redirect URIs must be absolute "
        "URIs and must not include a fragment component. At least one redirect URI and response type is required "
        "for all client types, with the following exceptions: If the client uses the Resource Owner Password "
        "flow (if `grant_type` contains the value password) or the Client Credentials flow (if `grant_type` "
        "contains the value `client_credentials`), then no redirect URI or response type is necessary. In these "
        "cases, you can pass either null or an empty array for these attributes.",
    )
    request_object_signing_alg: Optional[List[SigningAlgorithm]] = Field(
        default=None,
        description="The type of [JSON Web Key Set](https://tools.ietf.org/html/rfc7517#section-5) algorithm that must be "
        "used for signing request objects",
    )
    response_types: Optional[List[ResponseType]] = Field(
        default=None,
        description="Array of OAuth 2.0 response type strings. Default value: `[code]`",
    )
    token_endpoint_auth_method: Optional[EndpointAuthMethod] = None
    tos_uri: Optional[StrictStr] = Field(
        default=None,
        description="URL string of a web page providing the client's terms of service document",
    )
    __properties: ClassVar[List[str]] = [
        "application_type",
        "client_id",
        "client_id_issued_at",
        "client_name",
        "client_secret",
        "client_secret_expires_at",
        "frontchannel_logout_session_required",
        "frontchannel_logout_uri",
        "grant_types",
        "initiate_login_uri",
        "jwks_uri",
        "logo_uri",
        "policy_uri",
        "post_logout_redirect_uris",
        "redirect_uris",
        "request_object_signing_alg",
        "response_types",
        "token_endpoint_auth_method",
        "tos_uri",
    ]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of Client from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set(
            [
                "client_id",
                "client_id_issued_at",
                "client_secret",
                "client_secret_expires_at",
            ]
        )

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # set to None if client_secret (nullable) is None
        # and model_fields_set contains the field
        if self.client_secret is None and "client_secret" in self.model_fields_set:
            _dict["client_secret"] = None

        # set to None if client_secret_expires_at (nullable) is None
        # and model_fields_set contains the field
        if (
            self.client_secret_expires_at is None
            and "client_secret_expires_at" in self.model_fields_set
        ):
            _dict["client_secret_expires_at"] = None

        # set to None if frontchannel_logout_uri (nullable) is None
        # and model_fields_set contains the field
        if (
            self.frontchannel_logout_uri is None
            and "frontchannel_logout_uri" in self.model_fields_set
        ):
            _dict["frontchannel_logout_uri"] = None

        # set to None if logo_uri (nullable) is None
        # and model_fields_set contains the field
        if self.logo_uri is None and "logo_uri" in self.model_fields_set:
            _dict["logo_uri"] = None

        # set to None if policy_uri (nullable) is None
        # and model_fields_set contains the field
        if self.policy_uri is None and "policy_uri" in self.model_fields_set:
            _dict["policy_uri"] = None

        # set to None if tos_uri (nullable) is None
        # and model_fields_set contains the field
        if self.tos_uri is None and "tos_uri" in self.model_fields_set:
            _dict["tos_uri"] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of Client from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate(
            {
                "application_type": obj.get("application_type"),
                "client_id": obj.get("client_id"),
                "client_id_issued_at": obj.get("client_id_issued_at"),
                "client_name": obj.get("client_name"),
                "client_secret": obj.get("client_secret"),
                "client_secret_expires_at": obj.get("client_secret_expires_at"),
                "frontchannel_logout_session_required": obj.get(
                    "frontchannel_logout_session_required"
                ),
                "frontchannel_logout_uri": obj.get("frontchannel_logout_uri"),
                "grant_types": obj.get("grant_types"),
                "initiate_login_uri": obj.get("initiate_login_uri"),
                "jwks_uri": obj.get("jwks_uri"),
                "logo_uri": obj.get("logo_uri"),
                "policy_uri": obj.get("policy_uri"),
                "post_logout_redirect_uris": obj.get("post_logout_redirect_uris"),
                "redirect_uris": obj.get("redirect_uris"),
                "request_object_signing_alg": obj.get("request_object_signing_alg"),
                "response_types": obj.get("response_types"),
                "token_endpoint_auth_method": obj.get("token_endpoint_auth_method"),
                "tos_uri": obj.get("tos_uri"),
            }
        )
        return _obj
