# 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, StrictStr
from typing_extensions import Self

from okta.models.token_hook_response_commands_inner_value_inner_value import (
    TokenHookResponseCommandsInnerValueInnerValue,
)


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

    op: Optional[StrictStr] = Field(
        default=None,
        description="The name of one of the supported ops: `add`: Add a claim. `replace`: Modify an existing claim and "
        "update the token lifetime. `remove`: Remove an existing claim. #### `op: add` notes  <details> "
        '<summary>Add a claim</summary>    Add a claim    **Existing JSON**    ```   {     "employeeId": '
        '"00u12345678"   }   ```    **Operation**    ```   {     "commands": [       {         "type": '
        '"com.okta.assertion.patch",         "value": [           {             "op": "add",             '
        '"path": "/claims/extPatientId",             "value": "1234"           }         ]       },       '
        '{         "type": "com.okta.assertion.patch",         "value": [           {             "op": "add",   '
        '          "path": "/claims/external_guid",             "value": "F0384685-F87D-474B-848D-2058AC5655A7"  '
        '         }         ]       }     ]   }   ```    **Updated JSON**    ```   {     "employeeId": '
        '"00u12345678",     "extPatientId": 1234,     "external_guid": "F0384685-F87D-474B-848D-2058AC5655A7"   '
        "}   ```    > **Note:** If you use the `add` operation and include an existing claim in your response "
        "with a different value, that value is replaced. Use the `replace` operation instead. If you attempt to "
        "remove a system-specific claim or use an invalid operation, the entire PATCH fails and errors are "
        "logged in the token hooks events. See `op: replace` notes. </details>  <details> <summary>Add new "
        "members to existing JSON objects</summary>    If you have a JSON object in a claim called "
        "`employee_profile`, and you want to add the `department_id` member to the claim, the existing JSON is "
        "updated by specifying the claim in the path, followed by the name of the object member.    **Existing "
        'JSON**    ```   {     "employee_profile": {       "employee_id": "1234",       "name": "Anna"     }   } '
        '  ```    **Operation**    ```   {     "commands": [       {         "type": "com.okta.identity.patch",  '
        '       "value": [           {             "op": "add",             '
        '"path": "/claims/employee_profile/department_id",             "value": "4947"           }         ]     '
        '  }     ]   }   ```    **Updated JSON**    ```   {     "employee_profile": {       "employee_id": '
        '"1234",       "name": "Anna",       "department_id": "4947"     }   }   ```    > **Note:** If you '
        "attempt to add a member within a JSON object that doesn't exist or using an invalid operation, "
        "the entire PATCH fails and errors are logged in the token hooks events. </details>  <details> "
        "<summary>Add new elements to existing arrays</summary>    Append an element to an array by specifying "
        "the name of the array, followed by the index where you want to insert the element in the path. "
        "Alternatively, you can specify the array name followed by a hyphen (-) in the path to append an element "
        "at the end of the array. For example, you have an array that contains the user's preferred airports, "
        "and you want to add a new airport to the array. The existing target JSON object is updated by "
        "specifying the claim in the path, followed by the index of where to insert the claim.    **Existing "
        'JSON**    ```   {     "preferred_airports":[       "sjc",       "sfo",       "oak"     ]   }   ```    '
        '**Operation**    ```   {     "commands": [       {         "type": "com.okta.identity.patch",         '
        '"value": [           {             "op": "add",             "path": "/claims/preferred_airports/3",     '
        '        "value": "lax"           }         ]       }     ]   }   ```    **Updated JSON**    ```   {     '
        '"preferred_airports":[       "sjc",       "sfo",       "oak",       "lax"     ]   }   ```    > '
        "**Note:** If you attempt to add an element within an array that doesn't exist or specify an invalid "
        "index, the entire PATCH fails and errors are logged in the token hooks events. </details>  #### `op: "
        "replace` notes  <details> <summary>Modify an existing claim</summary>    You can modify (`replace`) "
        "existing custom claims or OIDC standard profile claims, such as `birthdate` and `locale`. You can't, "
        "however, modify any system-specific claims, such as `iss` or `ver`. Also, you can't modify a claim "
        "that isn't currently part of the token in the request payload. Attempting to modify a system-specific "
        "claim or using an invalid operation results in the entire PATCH failing and errors logged in the token "
        "hooks events.    See [Access Tokens Scopes and Claims]("
        "/openapi/okta-oauth/guides/overview/#access-token-scopes-and-claims) for the list of access "
        "token-reserved claims that you can't modify.    > **Note:** Although the `aud` and `sub` claims are "
        "listed as reserved claims, you can modify those claims in access tokens. You can't modify these claims "
        "in ID tokens.    See [ID Token Claims](/openapi/okta-oauth/guides/overview/#id-token-claims) for a list "
        "of ID token-reserved claims that you can't modify.    **Existing target JSON object**    ```   {     "
        '"employeeId": "00u12345678",     "extPatientId": 1234,     "external_guid": '
        '"F0384685-F87D-474B-848D-2058AC5655A7"   }   ```    **Operation**    ```   {     "commands": [       {  '
        '       "type": "com.okta.identity.patch",         "value": [           {             "op": "replace",   '
        '          "path": "/claims/extPatientId",             "value": "12345"           },           '
        '{             "op": "replace",             "path": "/claims/external_guid",             '
        '"value": "D1495796-G98E-585C-959E-1269CD6766B8"           }         ]       }     ]   }   ```    '
        '**Updated JSON***    ```   {     "employeeId": "00u12345678",     "extPatientId": 12345,     '
        '"external_guid": "D1495796-G98E-585C-959E-1269CD6766B8"   }   ```  </details>  <details> '
        "<summary>Modify members within existing JSON objects and arrays</summary>    Use the `replace` "
        "operation to modify members within JSON objects and elements within arrays. For example, you have a "
        "JSON object in a claim called `employee_profile`, and you want to update the email address of the "
        "employee. The existing target JSON object is updated by specifying the claim in the path, followed by "
        "the name of the object member that you want to modify.    **Existing target JSON object**    ```   {    "
        ' "employee_profile": {       "employee_id":"1234",       "name":"Anna",       '
        '"email":"anna.v@company.com"       }   }   ```    **Operation**    ```   {     "commands": [       {    '
        '     "type": "com.okta.identity.patch",         "value": [           {             "op": "replace",     '
        '        "path": "/claims/employee_profile/email",             "value": "anna@company.com"           }   '
        '      ]       }     ]   }   ```    **Updated JSON**    ```   {     "employee_profile": {       '
        '"employee_id":"1234",       "name":"Anna",       "email":"anna@company.com"       }   }   ```    > '
        "**Note:** If you attempt to modify a member within a JSON object that doesn't exist or use an invalid "
        "operation, the entire PATCH fails and errors are logged in the token hooks events.    Similarly, "
        "you can replace elements in an array by specifying the array name and the valid index of the element "
        "that you want to replace in the path. </details>  <details> <summary>Modify token lifetimes</summary>   "
        "You can modify how long the access and ID tokens are valid by specifying the `lifetime` in seconds. The "
        "`lifetime` value must be a minimum of five minutes (300 seconds) and a maximum of 24 hours (86,"
        '400 seconds).    **Operation**    ```   {     "commands": [       {         "type": '
        '"com.okta.identity.patch",         "value": [           {             "op": "replace",             '
        '"path": "/token/lifetime/expiration",             "value": 36000           }         ]       },       '
        '{         "type": "com.okta.access.patch",         "value": [           {             "op": "replace",  '
        '           "path": "/token/lifetime/expiration",             "value": 36000           }         ]       '
        "}     ]   }   ```  </details>  #### `op: remove` notes  <details> <summary>Remove a claim</summary>    "
        "You can remove existing custom claims or OIDC standard profile claims, such as `birthdate` or `locale`. "
        "You can't, however, remove any system-specific claims, such as `iss` or `ver`. You also can't remove "
        "a claim that isn't currently part of the token in the request payload. If you attempt to remove a "
        "system-specific claim or use an invalid operation, the entire PATCH fails and errors are logged in the "
        "token hooks events.    See [Access Tokens Scopes and Claims]("
        "/openapi/okta-oauth/guides/overview/#access-token-scopes-and-claims) for the list of access "
        "token-reserved claims that you can't modify.    See [ID Token Claims]("
        "/openapi/okta-oauth/guides/overview/#id-token-claims) for a list of ID token-reserved claims that you "
        'can\'t modify.    **Operation**    ```   {     "commands": [       {         "type": '
        '"com.okta.identity.patch",         "value": [           {             "op": "remove",             '
        '"path": "/claims/birthdate",             "value": null           }         ]       },       '
        '{         "type": "com.okta.access.patch",         "value": [           {             "op": "remove",   '
        '          "path": "/claims/external_guid"           }         ]       }     ]   }   ```    > **Note:** '
        "The `value` property for the `remove` operation isn't required. If you provide it in the response, "
        "it should be set to `null`. Providing any other value fails the entire PATCH response.  </details>  "
        "<details> <summary>Remove members from existing arrays</summary>    Use the `remove` operation to "
        "remove members from existing arrays. For example, you have an array that contains the user's preferred "
        "airports, and you want to remove an airport from the array. The existing target JSON object is updated "
        "by specifying the array name followed by the index of the element that you want to remove. You don't "
        "need to specify a value for the remove operation, but you can specify `null` as the value if you want.  "
        '  **Existing target JSON object**    ```   {     "preferred_airports": [         "sjc",         "lax",  '
        '       "sfo",         "oak"       ]   }   ```    **Operation**    ```   {     "commands": [       {     '
        '    "type": "com.okta.identity.patch",         "value": [           {             "op": "remove",       '
        '      "path": "/claims/preferred_airports/1"           }         ]       }     ]   }   ```    **Updated '
        'JSON**    ```   {     "preferred_airports": [         "sjc",         "sfo",         "oak"       ]   }   '
        "```  </details>  <details> <summary>Remove members from existing JSON objects</summary>   Use the "
        "`remove` operation to remove members from existing JSON objects. Do this by specifying the JSON object "
        "in the path, followed by the claim member that you would like to remove. For example, you have an "
        "`employee_profile` claim, and you want to remove `email` from it.  **Existing target JSON object**  ``` "
        '{   "employee_profile": {     "employee_id":"1234",     "name":"Anna",     "email":"anna.v@company.com" '
        '    } } ```  **Operation**  ``` {   "commands": [     {       "type": "com.okta.identity.patch",       '
        '"value": [         {           "op": "remove",           "path": "/claims/employee_profile/email"       '
        '  }       ]     }   ] } ```  **Updated JSON** ``` {   "employee_profile": {     "employee_id":"1234",   '
        '  "name":"Anna",     } } ```  </details>',
    )
    path: Optional[StrictStr] = Field(
        default=None,
        description="Location within the token to apply the operation, specified as a slash-delimited path. When you add, "
        "replace, or remove a claim, this path always begins with `/claims/` and is followed by the name of the "
        "new claim that you're adding. When you replace a token lifetime, the path should always be "
        "`/token/lifetime/expiration`.",
    )
    value: Optional[TokenHookResponseCommandsInnerValueInnerValue] = None
    __properties: ClassVar[List[str]] = ["op", "path", "value"]

    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 TokenHookResponseCommandsInnerValueInner 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.
        """
        excluded_fields: Set[str] = set([])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of value
        if self.value:
            if not isinstance(self.value, dict):
                _dict["value"] = self.value.to_dict()
            else:
                _dict["value"] = self.value

        return _dict

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

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

        _obj = cls.model_validate(
            {
                "op": obj.get("op"),
                "path": obj.get("path"),
                "value": (
                    TokenHookResponseCommandsInnerValueInnerValue.from_dict(
                        obj["value"]
                    )
                    if obj.get("value") is not None
                    else None
                ),
            }
        )
        return _obj
