# coding: utf-8

"""
    SnapTrade

    Connect brokerage accounts to your app for live positions and trading  # noqa: E501

    The version of the OpenAPI document: 1.0.0
    Contact: api@snaptrade.com
    Generated by: https://konfigthis.com
"""

from datetime import date, datetime  # noqa: F401
import decimal  # noqa: F401
import functools  # noqa: F401
import io  # noqa: F401
import re  # noqa: F401
import typing  # noqa: F401
import typing_extensions  # noqa: F401
import uuid  # noqa: F401

import frozendict  # noqa: F401

from snaptrade_client import schemas  # noqa: F401


class EncryptedResponse(
    schemas.DictSchema
):
    """NOTE: This class is auto generated by Konfig.
    Ref: https://konfigthis.com

    Do not edit the class manually.

    This response consists of 2 different components that must be decrypted to obtain the decrypted message

* Decrypting the encryptedSharedKey

  The encrypted shared key is a shared key that was randomly generated by SnapTrade and encrypted using the users SSH public key provided when registering the user
  It is needed to decrypt the message in step 2.

  To decrypt the shared key, the user should have access to their SSH private key stored locally in their device

  An example Python code on how to decrypt the shared key is shown below

  ```
  def decrypt_rsa_message(self, encrypted_message):
      from Crypto.Cipher import PKCS1_OAEP
      from Crypto.PublicKey import RSA
      from base64 import b64decode

      f = open('private.pem', 'r')
      private_key = RSA.import_key(f.read())
      cipher = PKCS1_OAEP.new(private_key)

      return cipher.decrypt(b64decode(encrypted_message.encode())).decode()
  ```

* Decrypting the encryptedMessageData

   The data meant to be returned by an endpoint can be obtained by decrypting the encrypted message

   An encrypted message is a message that is encrypted using AES - MODE OCB with the shared key obtained in step one

  An example code to decrypt the encrypted message is shown below

  ```
  def decrypt_aes_message(self, shared_key, encrypted_message):
      from Crypto.Cipher import AES
      from base64 import b64decode

      encrypted_msg = b64decode(encrypted_message["encryptedMessage"].encode())
      tag = b64decode(encrypted_message["tag"].encode())
      nonce = b64decode(encrypted_message["nonce"].encode())
      cipher = AES.new(shared_key.encode(), AES.MODE_OCB, nonce=nonce)

      return cipher.decrypt_and_verify(encrypted_msg, tag).decode()
  ```

    """


    class MetaOapg:
        
        class properties:
            encryptedSharedKey = schemas.StrSchema
            
            
            class encryptedMessageData(
                schemas.DictSchema
            ):
            
            
                class MetaOapg:
                    
                    class properties:
                        encryptedMessage = schemas.StrSchema
                        tag = schemas.StrSchema
                        nonce = schemas.StrSchema
                        __annotations__ = {
                            "encryptedMessage": encryptedMessage,
                            "tag": tag,
                            "nonce": nonce,
                        }
                    additional_properties = schemas.AnyTypeSchema
                
                @typing.overload
                def __getitem__(self, name: typing_extensions.Literal["encryptedMessage"]) -> MetaOapg.properties.encryptedMessage: ...
                
                @typing.overload
                def __getitem__(self, name: typing_extensions.Literal["tag"]) -> MetaOapg.properties.tag: ...
                
                @typing.overload
                def __getitem__(self, name: typing_extensions.Literal["nonce"]) -> MetaOapg.properties.nonce: ...
                
                @typing.overload
                def __getitem__(self, name: str) -> MetaOapg.additional_properties: ...
                
                def __getitem__(self, name: typing.Union[typing_extensions.Literal["encryptedMessage"], typing_extensions.Literal["tag"], typing_extensions.Literal["nonce"], str, ]):
                    # dict_instance[name] accessor
                    return super().__getitem__(name)
                
                @typing.overload
                def get_item_oapg(self, name: typing_extensions.Literal["encryptedMessage"]) -> typing.Union[MetaOapg.properties.encryptedMessage, schemas.Unset]: ...
                
                @typing.overload
                def get_item_oapg(self, name: typing_extensions.Literal["tag"]) -> typing.Union[MetaOapg.properties.tag, schemas.Unset]: ...
                
                @typing.overload
                def get_item_oapg(self, name: typing_extensions.Literal["nonce"]) -> typing.Union[MetaOapg.properties.nonce, schemas.Unset]: ...
                
                @typing.overload
                def get_item_oapg(self, name: str) -> typing.Union[MetaOapg.additional_properties, schemas.Unset]: ...
                
                def get_item_oapg(self, name: typing.Union[typing_extensions.Literal["encryptedMessage"], typing_extensions.Literal["tag"], typing_extensions.Literal["nonce"], str, ]):
                    return super().get_item_oapg(name)
            
                def __new__(
                    cls,
                    *args: typing.Union[dict, frozendict.frozendict, ],
                    encryptedMessage: typing.Union[MetaOapg.properties.encryptedMessage, str, schemas.Unset] = schemas.unset,
                    tag: typing.Union[MetaOapg.properties.tag, str, schemas.Unset] = schemas.unset,
                    nonce: typing.Union[MetaOapg.properties.nonce, str, schemas.Unset] = schemas.unset,
                    _configuration: typing.Optional[schemas.Configuration] = None,
                    **kwargs: typing.Union[MetaOapg.additional_properties, dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, ],
                ) -> 'encryptedMessageData':
                    return super().__new__(
                        cls,
                        *args,
                        encryptedMessage=encryptedMessage,
                        tag=tag,
                        nonce=nonce,
                        _configuration=_configuration,
                        **kwargs,
                    )
            __annotations__ = {
                "encryptedSharedKey": encryptedSharedKey,
                "encryptedMessageData": encryptedMessageData,
            }
        additional_properties = schemas.NotAnyTypeSchema
    
    @typing.overload
    def __getitem__(self, name: typing_extensions.Literal["encryptedSharedKey"]) -> MetaOapg.properties.encryptedSharedKey: ...
    
    @typing.overload
    def __getitem__(self, name: typing_extensions.Literal["encryptedMessageData"]) -> MetaOapg.properties.encryptedMessageData: ...
    
    def __getitem__(self, name: typing.Union[typing_extensions.Literal["encryptedSharedKey"], typing_extensions.Literal["encryptedMessageData"], ]):
        # dict_instance[name] accessor
        return super().__getitem__(name)
    
    @typing.overload
    def get_item_oapg(self, name: typing_extensions.Literal["encryptedSharedKey"]) -> typing.Union[MetaOapg.properties.encryptedSharedKey, schemas.Unset]: ...
    
    @typing.overload
    def get_item_oapg(self, name: typing_extensions.Literal["encryptedMessageData"]) -> typing.Union[MetaOapg.properties.encryptedMessageData, schemas.Unset]: ...
    
    def get_item_oapg(self, name: typing.Union[typing_extensions.Literal["encryptedSharedKey"], typing_extensions.Literal["encryptedMessageData"], ]):
        return super().get_item_oapg(name)

    def __new__(
        cls,
        *args: typing.Union[dict, frozendict.frozendict, ],
        encryptedSharedKey: typing.Union[MetaOapg.properties.encryptedSharedKey, str, schemas.Unset] = schemas.unset,
        encryptedMessageData: typing.Union[MetaOapg.properties.encryptedMessageData, dict, frozendict.frozendict, schemas.Unset] = schemas.unset,
        _configuration: typing.Optional[schemas.Configuration] = None,
    ) -> 'EncryptedResponse':
        return super().__new__(
            cls,
            *args,
            encryptedSharedKey=encryptedSharedKey,
            encryptedMessageData=encryptedMessageData,
            _configuration=_configuration,
        )
