# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# CDP domain: SmartCardEmulation (experimental)

from __future__ import annotations
import enum
import typing
from dataclasses import dataclass
from .util import event_class, T_JSON_DICT


class ResultCode(enum.Enum):
    """
    Indicates the PC/SC error code.
    This maps to:
    PC/SC Lite: https://pcsclite.apdu.fr/api/group__ErrorCodes.html
    Microsoft:
    https://learn.microsoft.com/en-us/windows/win32/secauthn/authentication-return-values
    """
    SUCCESS = "success"
    REMOVED_CARD = "removed-card"
    RESET_CARD = "reset-card"
    UNPOWERED_CARD = "unpowered-card"
    UNRESPONSIVE_CARD = "unresponsive-card"
    UNSUPPORTED_CARD = "unsupported-card"
    READER_UNAVAILABLE = "reader-unavailable"
    SHARING_VIOLATION = "sharing-violation"
    NOT_TRANSACTED = "not-transacted"
    NO_SMARTCARD = "no-smartcard"
    PROTO_MISMATCH = "proto-mismatch"
    SYSTEM_CANCELLED = "system-cancelled"
    NOT_READY = "not-ready"
    CANCELLED = "cancelled"
    INSUFFICIENT_BUFFER = "insufficient-buffer"
    INVALID_HANDLE = "invalid-handle"
    INVALID_PARAMETER = "invalid-parameter"
    INVALID_VALUE = "invalid-value"
    NO_MEMORY = "no-memory"
    TIMEOUT = "timeout"
    UNKNOWN_READER = "unknown-reader"
    UNSUPPORTED_FEATURE = "unsupported-feature"
    NO_READERS_AVAILABLE = "no-readers-available"
    SERVICE_STOPPED = "service-stopped"
    NO_SERVICE = "no-service"
    COMM_ERROR = "comm-error"
    INTERNAL_ERROR = "internal-error"
    SERVER_TOO_BUSY = "server-too-busy"
    UNEXPECTED = "unexpected"
    SHUTDOWN = "shutdown"
    UNKNOWN_CARD = "unknown-card"
    UNKNOWN = "unknown"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> ResultCode:
        return cls(json)


class ShareMode(enum.Enum):
    """Maps to the ``SCARD_SHARE_*`` values."""
    SHARED = "shared"
    EXCLUSIVE = "exclusive"
    DIRECT = "direct"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> ShareMode:
        return cls(json)


class Disposition(enum.Enum):
    """Indicates what the reader should do with the card."""
    LEAVE_CARD = "leave-card"
    RESET_CARD = "reset-card"
    UNPOWER_CARD = "unpower-card"
    EJECT_CARD = "eject-card"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> Disposition:
        return cls(json)


class ConnectionState(enum.Enum):
    """Maps to ``SCARD_*`` connection state values."""
    ABSENT = "absent"
    PRESENT = "present"
    SWALLOWED = "swallowed"
    POWERED = "powered"
    NEGOTIABLE = "negotiable"
    SPECIFIC = "specific"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> ConnectionState:
        return cls(json)


@dataclass
class ReaderStateFlags:
    """Maps to the ``SCARD_STATE_*`` flags."""
    unaware: typing.Optional[bool] = None
    ignore: typing.Optional[bool] = None
    changed: typing.Optional[bool] = None
    unknown: typing.Optional[bool] = None
    unavailable: typing.Optional[bool] = None
    empty: typing.Optional[bool] = None
    present: typing.Optional[bool] = None
    exclusive: typing.Optional[bool] = None
    inuse: typing.Optional[bool] = None
    mute: typing.Optional[bool] = None
    unpowered: typing.Optional[bool] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        if self.unaware is not None:
            json["unaware"] = self.unaware
        if self.ignore is not None:
            json["ignore"] = self.ignore
        if self.changed is not None:
            json["changed"] = self.changed
        if self.unknown is not None:
            json["unknown"] = self.unknown
        if self.unavailable is not None:
            json["unavailable"] = self.unavailable
        if self.empty is not None:
            json["empty"] = self.empty
        if self.present is not None:
            json["present"] = self.present
        if self.exclusive is not None:
            json["exclusive"] = self.exclusive
        if self.inuse is not None:
            json["inuse"] = self.inuse
        if self.mute is not None:
            json["mute"] = self.mute
        if self.unpowered is not None:
            json["unpowered"] = self.unpowered
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ReaderStateFlags:
        return cls(
            unaware=bool(json["unaware"])
            if json.get("unaware", None) is not None
            else None,
            ignore=bool(json["ignore"])
            if json.get("ignore", None) is not None
            else None,
            changed=bool(json["changed"])
            if json.get("changed", None) is not None
            else None,
            unknown=bool(json["unknown"])
            if json.get("unknown", None) is not None
            else None,
            unavailable=bool(json["unavailable"])
            if json.get("unavailable", None) is not None
            else None,
            empty=bool(json["empty"])
            if json.get("empty", None) is not None
            else None,
            present=bool(json["present"])
            if json.get("present", None) is not None
            else None,
            exclusive=bool(json["exclusive"])
            if json.get("exclusive", None) is not None
            else None,
            inuse=bool(json["inuse"])
            if json.get("inuse", None) is not None
            else None,
            mute=bool(json["mute"])
            if json.get("mute", None) is not None
            else None,
            unpowered=bool(json["unpowered"])
            if json.get("unpowered", None) is not None
            else None,
        )


@dataclass
class ProtocolSet:
    """Maps to the ``SCARD_PROTOCOL_*`` flags."""
    t0: typing.Optional[bool] = None
    t1: typing.Optional[bool] = None
    raw: typing.Optional[bool] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        if self.t0 is not None:
            json["t0"] = self.t0
        if self.t1 is not None:
            json["t1"] = self.t1
        if self.raw is not None:
            json["raw"] = self.raw
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ProtocolSet:
        return cls(
            t0=bool(json["t0"]) if json.get("t0", None) is not None else None,
            t1=bool(json["t1"]) if json.get("t1", None) is not None else None,
            raw=bool(json["raw"])
            if json.get("raw", None) is not None
            else None,
        )


class Protocol(enum.Enum):
    """Maps to the ``SCARD_PROTOCOL_*`` values."""
    T0 = "t0"
    T1 = "t1"
    RAW = "raw"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> Protocol:
        return cls(json)


@dataclass
class ReaderStateIn:
    reader: str
    current_state: ReaderStateFlags
    current_insertion_count: int

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["reader"] = self.reader
        json["currentState"] = self.current_state.to_json()
        json["currentInsertionCount"] = self.current_insertion_count
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ReaderStateIn:
        return cls(
            reader=str(json["reader"]),
            current_state=ReaderStateFlags.from_json(json["currentState"]),
            current_insertion_count=int(json["currentInsertionCount"]),
        )


@dataclass
class ReaderStateOut:
    reader: str
    event_state: ReaderStateFlags
    event_count: int
    atr: str

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["reader"] = self.reader
        json["eventState"] = self.event_state.to_json()
        json["eventCount"] = self.event_count
        json["atr"] = self.atr
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ReaderStateOut:
        return cls(
            reader=str(json["reader"]),
            event_state=ReaderStateFlags.from_json(json["eventState"]),
            event_count=int(json["eventCount"]),
            atr=str(json["atr"]),
        )


def enable() -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Enables the ``SmartCardEmulation`` domain."""
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.enable",
    }
    json = yield cmd_dict  # noqa


def disable() -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Disables the ``SmartCardEmulation`` domain."""
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.disable",
    }
    json = yield cmd_dict  # noqa


def report_establish_context_result(
    request_id: str, context_id: int
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Reports the successful result of a ``SCardEstablishContext`` call.
    :param request_id:
    :param context_id:
    """
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["contextId"] = context_id
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportEstablishContextResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_release_context_result(
    request_id: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Reports the successful result of a ``SCardReleaseContext`` call."""
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportReleaseContextResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_list_readers_result(
    request_id: str, readers: typing.List[str]
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Reports the successful result of a ``SCardListReaders`` call."""
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["readers"] = [i for i in readers]
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportListReadersResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_get_status_change_result(
    request_id: str, reader_states: typing.List[ReaderStateOut]
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Reports the successful result of a ``SCardGetStatusChange`` call."""
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["readerStates"] = [i.to_json() for i in reader_states]
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportGetStatusChangeResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_begin_transaction_result(
    request_id: str, handle: int
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Reports the result of a ``SCardBeginTransaction`` call.
    On success, this creates a new transaction object.
    """
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["handle"] = handle
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportBeginTransactionResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_plain_result(
    request_id: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Reports the successful result of a call that returns only a result code.
    Used for: ``SCardCancel``, ``SCardDisconnect``, ``SCardSetAttrib``,
    ``SCardEndTransaction``.
    """
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportPlainResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_connect_result(
    request_id: str,
    handle: int,
    active_protocol: typing.Optional[Protocol] = None,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Reports the successful result of a ``SCardConnect`` call."""
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["handle"] = handle
    if active_protocol is not None:
        params["activeProtocol"] = active_protocol.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportConnectResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_data_result(
    request_id: str, data: str
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Reports the successful result of a call that sends back data on success.
    Used for ``SCardTransmit``, ``SCardControl``, and ``SCardGetAttrib``.
    """
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["data"] = data
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportDataResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_status_result(
    request_id: str,
    reader_name: str,
    state: ConnectionState,
    atr: str,
    protocol: typing.Optional[Protocol] = None,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Reports the successful result of a ``SCardStatus`` call."""
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["readerName"] = reader_name
    params["state"] = state.to_json()
    params["atr"] = atr
    if protocol is not None:
        params["protocol"] = protocol.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportStatusResult",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def report_error(
    request_id: str, result_code: ResultCode
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Reports an error result for the given request."""
    params: T_JSON_DICT = dict()
    params["requestId"] = request_id
    params["resultCode"] = result_code.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "SmartCardEmulation.reportError",
        "params": params,
    }
    json = yield cmd_dict  # noqa


@event_class("SmartCardEmulation.establishContextRequested")
@dataclass
class EstablishContextRequested:
    """Fired when ``SCardEstablishContext`` is called."""
    request_id: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> EstablishContextRequested:
        return cls(request_id=str(json["requestId"]))


@event_class("SmartCardEmulation.releaseContextRequested")
@dataclass
class ReleaseContextRequested:
    """Fired when ``SCardReleaseContext`` is called."""
    request_id: str
    context_id: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ReleaseContextRequested:
        return cls(
            request_id=str(json["requestId"]),
            context_id=int(json["contextId"]),
        )


@event_class("SmartCardEmulation.listReadersRequested")
@dataclass
class ListReadersRequested:
    """Fired when ``SCardListReaders`` is called."""
    request_id: str
    context_id: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ListReadersRequested:
        return cls(
            request_id=str(json["requestId"]),
            context_id=int(json["contextId"]),
        )


@event_class("SmartCardEmulation.getStatusChangeRequested")
@dataclass
class GetStatusChangeRequested:
    """
    Fired when ``SCardGetStatusChange`` is called. Timeout is specified in
    milliseconds.
    """
    request_id: str
    context_id: int
    reader_states: typing.List[ReaderStateIn]
    #: in milliseconds, if absent, it means "infinite"
    timeout: typing.Optional[int]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> GetStatusChangeRequested:
        return cls(
            request_id=str(json["requestId"]),
            context_id=int(json["contextId"]),
            reader_states=[
                ReaderStateIn.from_json(i) for i in json["readerStates"]
            ],
            timeout=int(json["timeout"])
            if json.get("timeout", None) is not None
            else None,
        )


@event_class("SmartCardEmulation.cancelRequested")
@dataclass
class CancelRequested:
    """Fired when ``SCardCancel`` is called."""
    request_id: str
    context_id: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> CancelRequested:
        return cls(
            request_id=str(json["requestId"]),
            context_id=int(json["contextId"]),
        )


@event_class("SmartCardEmulation.connectRequested")
@dataclass
class ConnectRequested:
    """Fired when ``SCardConnect`` is called."""
    request_id: str
    context_id: int
    reader: str
    share_mode: ShareMode
    preferred_protocols: ProtocolSet

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ConnectRequested:
        return cls(
            request_id=str(json["requestId"]),
            context_id=int(json["contextId"]),
            reader=str(json["reader"]),
            share_mode=ShareMode.from_json(json["shareMode"]),
            preferred_protocols=ProtocolSet.from_json(
                json["preferredProtocols"]
            ),
        )


@event_class("SmartCardEmulation.disconnectRequested")
@dataclass
class DisconnectRequested:
    """Fired when ``SCardDisconnect`` is called."""
    request_id: str
    handle: int
    disposition: Disposition

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> DisconnectRequested:
        return cls(
            request_id=str(json["requestId"]),
            handle=int(json["handle"]),
            disposition=Disposition.from_json(json["disposition"]),
        )


@event_class("SmartCardEmulation.transmitRequested")
@dataclass
class TransmitRequested:
    """Fired when ``SCardTransmit`` is called."""
    request_id: str
    handle: int
    data: str
    protocol: typing.Optional[Protocol]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> TransmitRequested:
        return cls(
            request_id=str(json["requestId"]),
            handle=int(json["handle"]),
            data=str(json["data"]),
            protocol=Protocol.from_json(json["protocol"])
            if json.get("protocol", None) is not None
            else None,
        )


@event_class("SmartCardEmulation.controlRequested")
@dataclass
class ControlRequested:
    """Fired when ``SCardControl`` is called."""
    request_id: str
    handle: int
    control_code: int
    data: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ControlRequested:
        return cls(
            request_id=str(json["requestId"]),
            handle=int(json["handle"]),
            control_code=int(json["controlCode"]),
            data=str(json["data"]),
        )


@event_class("SmartCardEmulation.getAttribRequested")
@dataclass
class GetAttribRequested:
    """Fired when ``SCardGetAttrib`` is called."""
    request_id: str
    handle: int
    attrib_id: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> GetAttribRequested:
        return cls(
            request_id=str(json["requestId"]),
            handle=int(json["handle"]),
            attrib_id=int(json["attribId"]),
        )


@event_class("SmartCardEmulation.setAttribRequested")
@dataclass
class SetAttribRequested:
    """Fired when ``SCardSetAttrib`` is called."""
    request_id: str
    handle: int
    attrib_id: int
    data: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SetAttribRequested:
        return cls(
            request_id=str(json["requestId"]),
            handle=int(json["handle"]),
            attrib_id=int(json["attribId"]),
            data=str(json["data"]),
        )


@event_class("SmartCardEmulation.statusRequested")
@dataclass
class StatusRequested:
    """Fired when ``SCardStatus`` is called."""
    request_id: str
    handle: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> StatusRequested:
        return cls(
            request_id=str(json["requestId"]), handle=int(json["handle"])
        )


@event_class("SmartCardEmulation.beginTransactionRequested")
@dataclass
class BeginTransactionRequested:
    """Fired when ``SCardBeginTransaction`` is called."""
    request_id: str
    handle: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> BeginTransactionRequested:
        return cls(
            request_id=str(json["requestId"]), handle=int(json["handle"])
        )


@event_class("SmartCardEmulation.endTransactionRequested")
@dataclass
class EndTransactionRequested:
    """Fired when ``SCardEndTransaction`` is called."""
    request_id: str
    handle: int
    disposition: Disposition

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> EndTransactionRequested:
        return cls(
            request_id=str(json["requestId"]),
            handle=int(json["handle"]),
            disposition=Disposition.from_json(json["disposition"]),
        )
