"""
Generated by the output of the 'protocol' command of signald
Version: '0.12.0+git2021-01-30rce7ef396.5'
"""
from dataclasses import dataclass, field
import typing

from pysignald_async.util import JSONProtocol, nested_dataclass, locals_to_request


@nested_dataclass
class JsonMessageEnvelopev1:
    username: str = None
    uuid: str = None
    source: "JsonAddressv1" = None
    sourceDevice: int = None
    type: str = None
    relay: str = None
    timestamp: int = None
    timestampISO: str = None
    serverTimestamp: int = None
    serverDeliveredTimestamp: int = None
    hasLegacyMessage: bool = None
    hasContent: bool = None
    isUnidentifiedSender: bool = None
    dataMessage: "JsonDataMessagev1" = None
    syncMessage: "JsonSyncMessagev1" = None
    callMessage: "JsonCallMessagev0" = None
    receipt: "JsonReceiptMessagev0" = None
    typing: "JsonTypingMessagev0" = None


@nested_dataclass
class SendResponsev1:
    results: typing.List["JsonSendMessageResultv1"] = field(default_factory=list)
    timestamp: int = None


@nested_dataclass
class JsonVersionMessagev1:
    name: str = None
    version: str = None
    branch: str = None
    commit: str = None


@nested_dataclass
class JsonGroupV2Infov1:
    id: str = None
    revision: int = None
    title: str = None
    timer: int = None
    members: typing.List["JsonAddressv1"] = field(default_factory=list)
    pendingMembers: typing.List["JsonAddressv1"] = field(default_factory=list)
    requestingMembers: typing.List["JsonAddressv1"] = field(default_factory=list)
    inviteLink: str = None


@nested_dataclass
class LinkedDevicesv1:
    devices: typing.List["DeviceInfov0"] = field(default_factory=list)


@nested_dataclass
class JsonGroupJoinInfov1:
    groupID: str = None
    title: str = None
    memberCount: int = None
    addFromInviteLink: int = None
    revision: int = None
    pendingAdminApproval: bool = None


@nested_dataclass
class GroupInfov1:
    """
    A generic type that is used when the group version is not known
    """

    v1: "JsonGroupInfov1" = None
    v2: "JsonGroupV2Infov1" = None


@nested_dataclass
class SetProfilev1:
    account: str = None
    name: str = None
    avatarFile: str = None


@nested_dataclass
class JsonAddressv1:
    number: str = None
    uuid: str = None
    relay: str = None


@nested_dataclass
class Profilev1:
    """
    Information about a Signal user
    """

    name: str = None
    avatar: str = None
    address: "JsonAddressv1" = None
    capabilities: "Capabilitiesv1" = None
    color: str = None
    profile_name: str = None
    inbox_position: int = None
    expiration_time: int = None


@nested_dataclass
class GroupListv1:
    groups: typing.List["JsonGroupV2Infov1"] = field(default_factory=list)
    legacyGroups: typing.List["JsonGroupInfov1"] = field(default_factory=list)


@nested_dataclass
class ProfileListv1:
    profiles: typing.List["Profilev1"] = field(default_factory=list)


@nested_dataclass
class JsonDataMessagev1:
    timestamp: int = None
    attachments: typing.List["JsonAttachmentv0"] = field(default_factory=list)
    body: str = None
    group: "JsonGroupInfov1" = None
    groupV2: "JsonGroupV2Infov1" = None
    endSession: bool = None
    expiresInSeconds: int = None
    profileKeyUpdate: bool = None
    quote: "JsonQuotev1" = None
    contacts: typing.List["SharedContactv0"] = field(default_factory=list)
    previews: typing.List["JsonPreviewv0"] = field(default_factory=list)
    sticker: "JsonStickerv0" = None
    viewOnce: bool = None
    reaction: "JsonReactionv1" = None
    remoteDelete: "RemoteDeletev0" = None
    mentions: typing.List["JsonMentionv1"] = field(default_factory=list)


@nested_dataclass
class JsonSyncMessagev1:
    sent: "JsonSentTranscriptMessagev1" = None
    contacts: "JsonAttachmentv0" = None
    contactsComplete: bool = None
    groups: "JsonAttachmentv0" = None
    blockedList: "JsonBlockedListMessagev1" = None
    request: str = None
    readMessages: typing.List["JsonReadMessagev1"] = field(default_factory=list)
    viewOnceOpen: "JsonViewOnceOpenMessagev1" = None
    verified: "JsonVerifiedMessagev1" = None
    configuration: "ConfigurationMessagev0" = None
    stickerPackOperations: typing.List["JsonStickerPackOperationMessagev0"] = field(
        default_factory=list
    )
    fetchType: str = None
    messageRequestResponse: "JsonMessageRequestResponseMessagev1" = None


@nested_dataclass
class JsonQuotev1:
    """
    A quote is a reply to a previous message. ID is the sent time of the message being replied to
    """

    id: int = None
    author: "JsonAddressv1" = None
    text: str = None
    attachments: typing.List["JsonQuotedAttachmentv0"] = field(default_factory=list)
    mentions: typing.List["JsonMentionv1"] = field(default_factory=list)


@nested_dataclass
class JsonMentionv1:
    uuid: str = None
    start: int = None
    length: int = None


@nested_dataclass
class JsonSendMessageResultv1:
    address: "JsonAddressv1" = None
    success: "Successv0" = None
    networkFailure: bool = None
    unregisteredFailure: bool = None
    identityFailure: str = None


@nested_dataclass
class JsonReactionv1:
    emoji: str = None
    remove: bool = None
    targetAuthor: "JsonAddressv1" = None
    targetSentTimestamp: int = None


@nested_dataclass
class JsonGroupInfov1:
    groupId: str = None
    members: typing.List["JsonAddressv1"] = field(default_factory=list)
    name: str = None
    type: str = None
    avatarId: int = None


@nested_dataclass
class Capabilitiesv1:
    gv2: bool = None
    storage: bool = None
    gv1_migration: bool = None


@nested_dataclass
class JsonSentTranscriptMessagev1:
    destination: "JsonAddressv1" = None
    timestamp: int = None
    expirationStartTimestamp: int = None
    message: "JsonDataMessagev1" = None
    unidentifiedStatus: dict = None
    isRecipientUpdate: bool = None


@nested_dataclass
class JsonBlockedListMessagev1:
    addresses: typing.List["JsonAddressv1"] = field(default_factory=list)
    groupIds: typing.List[str] = field(default_factory=list)


@nested_dataclass
class JsonReadMessagev1:
    sender: "JsonAddressv1" = None
    timestamp: int = None


@nested_dataclass
class JsonViewOnceOpenMessagev1:
    sender: "JsonAddressv1" = None
    timestamp: int = None


@nested_dataclass
class JsonVerifiedMessagev1:
    destination: "JsonAddressv1" = None
    identityKey: str = None
    verified: str = None
    timestamp: int = None


@nested_dataclass
class JsonAccountListv0:
    accounts: typing.List["JsonAccountv0"] = field(default_factory=list)


@nested_dataclass
class JsonCallMessagev0:
    offerMessage: "OfferMessagev0" = None
    answerMessage: "AnswerMessagev0" = None
    busyMessage: "BusyMessagev0" = None
    hangupMessage: "HangupMessagev0" = None
    iceUpdateMessages: typing.List["IceUpdateMessagev0"] = field(default_factory=list)
    destinationDeviceId: int = None
    isMultiRing: bool = None


@nested_dataclass
class JsonReceiptMessagev0:
    type: str = None
    timestamps: typing.List[int] = field(default_factory=list)
    when: int = None


@nested_dataclass
class JsonTypingMessagev0:
    action: str = None
    timestamp: int = None
    groupId: str = None


@nested_dataclass
class JsonAccountv0:
    deviceId: int = None
    username: str = None
    filename: str = None
    uuid: str = None
    registered: bool = None
    has_keys: bool = None
    subscribed: bool = None


@nested_dataclass
class JsonAttachmentv0:
    contentType: str = None
    id: str = None
    size: int = None
    storedFilename: str = None
    filename: str = None
    customFilename: str = None
    caption: str = None
    width: int = None
    height: int = None
    voiceNote: bool = None
    key: str = None
    digest: str = None
    blurhash: str = None


@nested_dataclass
class DeviceInfov0:
    id: int = None
    name: str = None
    created: int = None
    lastSeen: int = None


@nested_dataclass
class SharedContactv0:
    name: "Namev0" = None
    avatar: "Optionalv0" = None
    phone: "Optionalv0" = None
    email: "Optionalv0" = None
    address: "Optionalv0" = None
    organization: "Optionalv0" = None


@nested_dataclass
class JsonPreviewv0:
    url: str = None
    title: str = None
    attachment: "JsonAttachmentv0" = None


@nested_dataclass
class JsonStickerv0:
    packID: str = None
    packKey: str = None
    stickerID: int = None
    attachment: "JsonAttachmentv0" = None


@nested_dataclass
class RemoteDeletev0:
    targetSentTimestamp: int = None


@nested_dataclass
class ConfigurationMessagev0:
    readReceipts: "Optionalv0" = None
    unidentifiedDeliveryIndicators: "Optionalv0" = None
    typingIndicators: "Optionalv0" = None
    linkPreviews: "Optionalv0" = None


@nested_dataclass
class JsonStickerPackOperationMessagev0:
    packID: str = None
    packKey: str = None
    type: str = None


@nested_dataclass
class OfferMessagev0:
    id: int = None
    sdp: str = None
    type: "Typev0" = None
    opaque: str = None


@nested_dataclass
class AnswerMessagev0:
    id: int = None
    sdp: str = None
    opaque: str = None


@nested_dataclass
class BusyMessagev0:
    id: int = None


@nested_dataclass
class HangupMessagev0:
    id: int = None
    type: "Typev0" = None
    deviceId: int = None
    legacy: bool = None


@nested_dataclass
class IceUpdateMessagev0:
    id: int = None
    opaque: str = None
    sdp: str = None


@nested_dataclass
class JsonQuotedAttachmentv0:
    contentType: str = None
    fileName: str = None
    thumbnail: "JsonAttachmentv0" = None


@nested_dataclass
class Successv0:
    unidentified: bool = None
    needsSync: bool = None
    duration: int = None


@nested_dataclass
class Namev0:
    display: "Optionalv0" = None
    given: "Optionalv0" = None
    family: "Optionalv0" = None
    prefix: "Optionalv0" = None
    suffix: "Optionalv0" = None
    middle: "Optionalv0" = None


@nested_dataclass
class Optionalv0:
    present: bool = None


@nested_dataclass
class Typev0:
    pass


@nested_dataclass
class LinkedDevicesv1alpha1:
    devices: typing.List["DeviceInfov0"] = field(default_factory=list)


@nested_dataclass
class JsonGroupJoinInfov1alpha1:
    groupID: str = None
    title: str = None
    memberCount: int = None
    addFromInviteLink: int = None
    revision: int = None
    pendingAdminApproval: bool = None


@nested_dataclass
class JsonGroupV2Infov1alpha1:
    id: str = None
    revision: int = None
    title: str = None
    timer: int = None
    members: typing.List["JsonAddressv1"] = field(default_factory=list)
    pendingMembers: typing.List["JsonAddressv1"] = field(default_factory=list)
    requestingMembers: typing.List["JsonAddressv1"] = field(default_factory=list)
    inviteLink: str = None


@nested_dataclass
class GroupInfov1alpha2:
    """
    A generic type that is used when the group version is not known
    """

    v1: "JsonGroupInfov1" = None
    v2: "JsonGroupV2Infov1" = None


class SignaldGeneratedAPI(JSONProtocol):
    async def send(
        self,
        username: str = None,
        recipientAddress: "JsonAddressv1" = None,
        recipientGroupId: str = None,
        messageBody: str = None,
        attachments: typing.List["JsonAttachmentv0"] = None,
        quote: "JsonQuotev1" = None,
        timestamp: int = None,
        mentions: typing.List["JsonMentionv1"] = None,
    ) -> SendResponsev1:
        """


        username: Example: "+12024561414"
        recipientAddress:
        recipientGroupId: Example: "EdSqI90cS0UomDpgUXOlCoObWvQOXlH5G3Z2d3f4ayE="
        messageBody: Example: "hello"
        attachments:
        quote:
        timestamp:
        mentions:
        """

        return SendResponsev1(
            **await self.get_response(
                {"type": "send", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def react(
        self,
        username: str = None,
        recipientAddress: "JsonAddressv1" = None,
        recipientGroupId: str = None,
        reaction: "JsonReactionv1" = None,
        timestamp: int = None,
    ) -> SendResponsev1:
        """
        react to a previous message

        username: Example: "+12024561414"
        recipientAddress:
        recipientGroupId: Example: "EdSqI90cS0UomDpgUXOlCoObWvQOXlH5G3Z2d3f4ayE="
        reaction:
        timestamp:
        """

        return SendResponsev1(
            **await self.get_response(
                {"type": "react", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def version(
        self,
    ) -> JsonVersionMessagev1:
        """"""

        return JsonVersionMessagev1(
            **await self.get_response(
                {"type": "version", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def accept_invitation(
        self,
        account: str = None,
        groupID: str = None,
    ) -> JsonGroupV2Infov1:
        """
        Accept a v2 group invitation. Note that you must have a profile name set to join groups.

        account: The account to interact with. Example: "+12024561414"
        groupID: Example: "EdSqI90cS0UomDpgUXOlCoObWvQOXlH5G3Z2d3f4ayE="
        """

        return JsonGroupV2Infov1(
            **await self.get_response(
                {
                    "type": "accept_invitation",
                    "version": "v1",
                    **locals_to_request(locals()),
                }
            )
        )

    async def approve_membership(
        self,
        account: str = None,
        groupID: str = None,
        members: typing.List["JsonAddressv1"] = None,
    ) -> JsonGroupV2Infov1:
        """
        approve a request to join a group

        account: The account to interact with. Example: "+12024561414"
        groupID: Example: "EdSqI90cS0UomDpgUXOlCoObWvQOXlH5G3Z2d3f4ayE="
        members: list of requesting members to approve.
        """

        return JsonGroupV2Infov1(
            **await self.get_response(
                {
                    "type": "approve_membership",
                    "version": "v1",
                    **locals_to_request(locals()),
                }
            )
        )

    async def get_group(
        self,
        account: str = None,
        groupID: str = None,
        revision: int = None,
    ) -> JsonGroupV2Infov1:
        """
        Query the server for the latest state of a known group

        account: The account to interact with. Example: "+12024561414"
        groupID: Example: "EdSqI90cS0UomDpgUXOlCoObWvQOXlH5G3Z2d3f4ayE="
        revision: the latest known revision, default value (-1) forces fetch from server.
        """

        return JsonGroupV2Infov1(
            **await self.get_response(
                {"type": "get_group", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def get_linked_devices(
        self,
        account: str = None,
    ) -> LinkedDevicesv1:
        """
        list all linked devices on a Signal account

        account: The account to interact with. Example: "+12024561414"
        """

        return LinkedDevicesv1(
            **await self.get_response(
                {
                    "type": "get_linked_devices",
                    "version": "v1",
                    **locals_to_request(locals()),
                }
            )
        )

    async def join_group(
        self,
        account: str = None,
        uri: str = None,
    ) -> JsonGroupJoinInfov1:
        """
        Join a group using the a signal.group URL. Note that you must have a profile name set to join groups.

        account: The account to interact with. Example: "+12024561414"
        uri: The signal.group URL. Example: "https://signal.group/#CjQKINH_GZhXhfifTcnBkaKTNRxW-hHKnGSq-cJNyPVqHRp8EhDUB7zjKNEl0NaULhsqJCX3"
        """

        return JsonGroupJoinInfov1(
            **await self.get_response(
                {"type": "join_group", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def protocol(
        self,
    ):
        """"""

        await self.get_response(
            {"type": "protocol", "version": "v1", **locals_to_request(locals())}
        )

    async def remove_linked_device(
        self,
        account: str = None,
        deviceId: int = None,
    ):
        """
        Remove a linked device from the Signal account. Only allowed when the local device id is 1

        account: The account to interact with. Example: "+12024561414"
        deviceId: the ID of the device to unlink. Example: 3
        """

        await self.get_response(
            {
                "type": "remove_linked_device",
                "version": "v1",
                **locals_to_request(locals()),
            }
        )

    async def update_group(
        self,
        account: str = None,
        groupID: str = None,
        title: str = None,
        avatar: str = None,
        addMembers: typing.List["JsonAddressv1"] = None,
        removeMembers: typing.List["JsonAddressv1"] = None,
    ) -> GroupInfov1:
        """
        modify a group

        account: The identifier of the account to interact with. Example: "+12024561414"
        groupID: Example: "EdSqI90cS0UomDpgUXOlCoObWvQOXlH5G3Z2d3f4ayE="
        title: Example: "Parkdale Run Club"
        avatar: Example: "/tmp/image.jpg"
        addMembers:
        removeMembers:
        """

        return GroupInfov1(
            **await self.get_response(
                {"type": "update_group", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def set_profile(
        self,
        account: str = None,
        name: str = None,
        avatarFile: str = None,
    ):
        """


        account: The phone number of the account to use. Example: "+12024561414"
        name: New profile name. Set to empty string for no profile name. Example: "signald user"
        avatarFile: Path to new profile avatar file, if the avatar should be updated. Example: "/tmp/image.jpg"
        """

        await self.get_response(
            {"type": "set_profile", "version": "v1", **locals_to_request(locals())}
        )

    async def resolve_address(
        self,
        account: str = None,
        partial: "JsonAddressv1" = None,
    ) -> JsonAddressv1:
        """
        Resolve a partial JsonAddress with only a number or UUID to one with both. Anywhere that signald accepts a JsonAddress will except a partial, this is a convenience function for client authors, mostly because signald doesn't resolve all the partials it returns

        account: The signal account to use. Example: "+12024561414"
        partial: The partial address, missing fields.
        """

        return JsonAddressv1(
            **await self.get_response(
                {
                    "type": "resolve_address",
                    "version": "v1",
                    **locals_to_request(locals()),
                }
            )
        )

    async def mark_read(
        self,
        account: str = None,
        to: "JsonAddressv1" = None,
        timestamps: typing.List[int] = None,
    ):
        """


        account: The account to interact with. Example: "+12024561414"
        to: The address that sent the message being marked as read.
        timestamps: List of messages to mark as read. Example: 1612005182278
        """

        await self.get_response(
            {"type": "mark_read", "version": "v1", **locals_to_request(locals())}
        )

    async def get_profile(
        self,
        account: str = None,
        async_: bool = None,
        address: "JsonAddressv1" = None,
    ) -> Profilev1:
        """
        Get all information available about a user

        account: the signald account to use.
        async_: return results from local store immediately, refreshing from server if needed. If false (default), block until all pending profiles have been retrieved..
        address: the address to look up.
        """

        return Profilev1(
            **await self.get_response(
                {"type": "get_profile", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def list_groups(
        self,
        account: str = None,
    ) -> GroupListv1:
        """


        account:
        """

        return GroupListv1(
            **await self.get_response(
                {"type": "list_groups", "version": "v1", **locals_to_request(locals())}
            )
        )

    async def list_contacts(
        self,
        account: str = None,
        async_: bool = None,
    ) -> ProfileListv1:
        """


        account:
        async_: return results from local store immediately, refreshing from server if needed. If false (default), block until all pending profiles have been retrieved..
        """

        return ProfileListv1(
            **await self.get_response(
                {
                    "type": "list_contacts",
                    "version": "v1",
                    **locals_to_request(locals()),
                }
            )
        )
