# DO NOT EDIT THIS FILE!
#
# This file is generated from the WebDriver BiDi specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# WebDriver BiDi module: bluetooth
"""
WebDriver BiDi bluetooth module.

Provides a simulation API for Web Bluetooth, allowing tests to fake
Bluetooth adapters, nearby peripherals, GATT services, characteristics,
and descriptors without physical hardware.
"""

from __future__ import annotations

from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any

from selenium.webdriver.common.bidi.common import command_builder
from selenium.webdriver.common.bidi._event_manager import EventConfig, _EventWrapper, _EventManager

@dataclass
class BluetoothManufacturerData:
    """BluetoothManufacturerData."""

    key: Any | None = None


@dataclass
class CharacteristicProperties:
    """CharacteristicProperties."""

    broadcast: bool | None = None
    read: bool | None = None
    write_without_response: bool | None = None
    write: bool | None = None
    notify: bool | None = None
    indicate: bool | None = None
    authenticated_signed_writes: bool | None = None
    extended_properties: bool | None = None


@dataclass
class RequestDeviceInfo:
    """
    Identifies a simulated Bluetooth device returned in a device-request prompt.

    Attributes:
        id: The internal device identifier.
        name: The human-readable device name shown in the prompt.
    """

    id: Any | None = None
    name: Any | None = None


@dataclass
class ScanRecord:
    """ScanRecord."""

    name: str | None = None
    uuids: list[Any] = field(default_factory=list)
    appearance: Any | None = None
    manufacturer_data: list[Any] = field(default_factory=list)


@dataclass
class HandleRequestDevicePromptParameters:
    """HandleRequestDevicePromptParameters."""

    context: str | None = None
    prompt: Any | None = None


@dataclass
class HandleRequestDevicePromptAcceptParameters:
    """HandleRequestDevicePromptAcceptParameters."""

    accept: Any | None = None
    device: Any | None = None


@dataclass
class HandleRequestDevicePromptCancelParameters:
    """HandleRequestDevicePromptCancelParameters."""

    accept: Any | None = None


@dataclass
class SimulateAdapterParameters:
    """
    Parameters for simulating a Bluetooth adapter state.

    Attributes:
        context: The browsing context ID to target.
        le_supported: Whether the adapter supports Bluetooth Low Energy.
        state: Adapter power state (e.g. 'powered-on', 'powered-off', 'absent').
    """

    context: str | None = None
    le_supported: bool | None = None
    state: Any | None = None


@dataclass
class DisableSimulationParameters:
    """DisableSimulationParameters."""

    context: str | None = None


@dataclass
class SimulatePreconnectedPeripheralParameters:
    """
    Parameters for adding a pre-connected simulated peripheral.

    Attributes:
        context: The browsing context ID to target.
        address: The Bluetooth device address (e.g. '09:09:09:09:09:09').
        name: The device name advertised to the page.
        manufacturer_data: List of manufacturer-specific data records.
        known_service_uuids: UUIDs of GATT services the device exposes.
    """

    context: str | None = None
    address: str | None = None
    name: str | None = None
    manufacturer_data: list[Any] = field(default_factory=list)
    known_service_uuids: list[Any] = field(default_factory=list)


@dataclass
class SimulateAdvertisementParameters:
    """
    Parameters for injecting a simulated advertisement packet.

    Attributes:
        context: The browsing context ID to target.
        scan_entry: The advertisement scan record to inject.
    """

    context: str | None = None
    scan_entry: Any | None = None


@dataclass
class SimulateAdvertisementScanEntryParameters:
    """SimulateAdvertisementScanEntryParameters."""

    device_address: str | None = None
    rssi: Any | None = None
    scan_record: Any | None = None


@dataclass
class SimulateGattConnectionResponseParameters:
    """
    Parameters for simulating a GATT connection response.

    Attributes:
        context: The browsing context ID to target.
        address: The address of the peripheral.
        code: The ATT error code (0 = success).
    """

    context: str | None = None
    address: str | None = None
    code: int | None = None


@dataclass
class SimulateGattDisconnectionParameters:
    """SimulateGattDisconnectionParameters."""

    context: str | None = None
    address: str | None = None


@dataclass
class SimulateServiceParameters:
    """SimulateServiceParameters."""

    context: str | None = None
    address: str | None = None
    uuid: Any | None = None
    type: Any | None = None


@dataclass
class SimulateCharacteristicParameters:
    """
    Parameters for adding a simulated GATT characteristic to a service.

    Attributes:
        context: The browsing context ID to target.
        address: The peripheral address.
        service: The service UUID the characteristic belongs to.
        characteristic: UUID of the characteristic.
        properties: Supported operations (read, write, notify, etc.).
    """

    context: str | None = None
    address: str | None = None
    service_uuid: Any | None = None
    characteristic_uuid: Any | None = None
    characteristic_properties: Any | None = None
    type: Any | None = None


@dataclass
class SimulateCharacteristicResponseParameters:
    """SimulateCharacteristicResponseParameters."""

    context: str | None = None
    address: str | None = None
    service_uuid: Any | None = None
    characteristic_uuid: Any | None = None
    type: Any | None = None
    code: int | None = None
    data: list[Any] = field(default_factory=list)


@dataclass
class SimulateDescriptorParameters:
    """SimulateDescriptorParameters."""

    context: str | None = None
    address: str | None = None
    service_uuid: Any | None = None
    characteristic_uuid: Any | None = None
    descriptor_uuid: Any | None = None
    type: Any | None = None


@dataclass
class SimulateDescriptorResponseParameters:
    """SimulateDescriptorResponseParameters."""

    context: str | None = None
    address: str | None = None
    service_uuid: Any | None = None
    characteristic_uuid: Any | None = None
    descriptor_uuid: Any | None = None
    type: Any | None = None
    code: int | None = None
    data: list[Any] = field(default_factory=list)


@dataclass
class RequestDevicePromptUpdatedParameters:
    """RequestDevicePromptUpdatedParameters."""

    context: str | None = None
    prompt: Any | None = None
    devices: list[Any] = field(default_factory=list)


@dataclass
class GattConnectionAttemptedParameters:
    """GattConnectionAttemptedParameters."""

    context: str | None = None
    address: str | None = None


@dataclass
class CharacteristicEventGeneratedParameters:
    """CharacteristicEventGeneratedParameters."""

    context: str | None = None
    address: str | None = None
    service_uuid: Any | None = None
    characteristic_uuid: Any | None = None
    type: Any | None = None
    data: list[Any] = field(default_factory=list)


@dataclass
class DescriptorEventGeneratedParameters:
    """DescriptorEventGeneratedParameters."""

    context: str | None = None
    address: str | None = None
    service_uuid: Any | None = None
    characteristic_uuid: Any | None = None
    descriptor_uuid: Any | None = None
    type: Any | None = None
    data: list[Any] = field(default_factory=list)


# BiDi Event Name to Parameter Type Mapping
EVENT_NAME_MAPPING = {
    "request_device_prompt_updated": "bluetooth.requestDevicePromptUpdated",
    "gatt_connection_attempted": "bluetooth.gattConnectionAttempted",
}

class Bluetooth:
    """
    BiDi interface for simulating Web Bluetooth hardware.

    Simulate adapters, peripherals, GATT services, characteristics,
    and descriptors without physical hardware.
    """

    EVENT_CONFIGS: dict[str, EventConfig] = {}
    def __init__(self, conn) -> None:
        self._conn = conn
        self._event_manager = _EventManager(conn, self.EVENT_CONFIGS)

    def handle_request_device_prompt(self, context: Any | None = None, prompt: Any | None = None):
        """
        Dismiss or accept a Bluetooth device-chooser prompt.

        Args:
            context: The browsing context containing the prompt.
            prompt: The prompt ID returned in the prompt-opened event.
        """
        if context is None:
            raise TypeError("handle_request_device_prompt() missing required argument: 'context'")
        if prompt is None:
            raise TypeError("handle_request_device_prompt() missing required argument: 'prompt'")

        params = {
            "context": context,
            "prompt": prompt,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.handleRequestDevicePrompt", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_adapter(self, context: Any | None = None, le_supported: bool | None = None, state: Any | None = None):
        """
        Simulate a Bluetooth adapter in the given browsing context.

        Args:
            context: The browsing context ID to target.
            le_supported: Whether Low Energy is supported.
            state: Adapter state ('powered-on', 'powered-off', 'absent').
        """
        if context is None:
            raise TypeError("simulate_adapter() missing required argument: 'context'")
        if state is None:
            raise TypeError("simulate_adapter() missing required argument: 'state'")

        params = {
            "context": context,
            "leSupported": le_supported,
            "state": state,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateAdapter", params)
        result = self._conn.execute(cmd)
        return result

    def disable_simulation(self, context: Any | None = None):
        """
        Disable all Bluetooth simulation in the given context, restoring real behaviour.

        Args:
            context: The browsing context ID to stop simulating.
        """
        if context is None:
            raise TypeError("disable_simulation() missing required argument: 'context'")

        params = {
            "context": context,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.disableSimulation", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_preconnected_peripheral(
        self,
        context: Any | None = None,
        address: Any | None = None,
        name: Any | None = None,
        manufacturer_data: list[Any] | None = None,
        known_service_uuids: list[Any] | None = None,
    ):
        """
        Register a simulated peripheral as already connected to the adapter.

        Args:
            context: The browsing context ID to target.
            address: The Bluetooth device address.
            name: The device name.
            manufacturer_data: Manufacturer-specific advertisement data.
            known_service_uuids: List of GATT service UUIDs the device exposes.
        """
        if context is None:
            raise TypeError("simulate_preconnected_peripheral() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_preconnected_peripheral() missing required argument: 'address'")
        if name is None:
            raise TypeError("simulate_preconnected_peripheral() missing required argument: 'name'")
        if manufacturer_data is None:
            raise TypeError("simulate_preconnected_peripheral() missing required argument: 'manufacturer_data'")
        if known_service_uuids is None:
            raise TypeError("simulate_preconnected_peripheral() missing required argument: 'known_service_uuids'")

        params = {
            "context": context,
            "address": address,
            "name": name,
            "manufacturerData": manufacturer_data,
            "knownServiceUuids": known_service_uuids,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulatePreconnectedPeripheral", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_advertisement(self, context: Any | None = None, scan_entry: Any | None = None):
        """
        Inject a simulated Bluetooth advertisement packet.

        Args:
            context: The browsing context ID to target.
            scan_entry: The advertisement scan record to inject.
        """
        if context is None:
            raise TypeError("simulate_advertisement() missing required argument: 'context'")
        if scan_entry is None:
            raise TypeError("simulate_advertisement() missing required argument: 'scan_entry'")

        params = {
            "context": context,
            "scanEntry": scan_entry,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateAdvertisement", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_gatt_connection_response(
        self,
        context: Any | None = None,
        address: Any | None = None,
        code: int | None = None,
    ):
        """
        Respond to a pending GATT connection attempt from the page.

        Args:
            context: The browsing context ID.
            address: The peripheral address.
            code: ATT error code (0 = success; non-zero signals failure).
        """
        if context is None:
            raise TypeError("simulate_gatt_connection_response() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_gatt_connection_response() missing required argument: 'address'")
        if code is None:
            raise TypeError("simulate_gatt_connection_response() missing required argument: 'code'")

        params = {
            "context": context,
            "address": address,
            "code": code,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateGattConnectionResponse", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_gatt_disconnection(self, context: Any | None = None, address: Any | None = None):
        """
        Simulate a GATT disconnection for the given peripheral.

        Args:
            context: The browsing context ID.
            address: The address of the peripheral to disconnect.
        """
        if context is None:
            raise TypeError("simulate_gatt_disconnection() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_gatt_disconnection() missing required argument: 'address'")

        params = {
            "context": context,
            "address": address,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateGattDisconnection", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_service(
        self,
        context: Any | None = None,
        address: Any | None = None,
        uuid: Any | None = None,
        type: Any | None = None,
    ):
        """
        Add a simulated GATT service to a peripheral.

        Args:
            context: The browsing context ID.
            address: The peripheral address.
            uuid: The service UUID.
        """
        if context is None:
            raise TypeError("simulate_service() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_service() missing required argument: 'address'")
        if uuid is None:
            raise TypeError("simulate_service() missing required argument: 'uuid'")
        if type is None:
            raise TypeError("simulate_service() missing required argument: 'type'")

        params = {
            "context": context,
            "address": address,
            "uuid": uuid,
            "type": type,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateService", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_characteristic(
        self,
        context: Any | None = None,
        address: Any | None = None,
        service_uuid: Any | None = None,
        characteristic_uuid: Any | None = None,
        characteristic_properties: Any | None = None,
        type: Any | None = None,
    ):
        """
        Add a simulated GATT characteristic to a service.

        Args:
            context: The browsing context ID.
            address: The peripheral address.
            service: The service UUID.
            characteristic: The characteristic UUID.
            properties: Supported operations bitmap.
        """
        if context is None:
            raise TypeError("simulate_characteristic() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_characteristic() missing required argument: 'address'")
        if service_uuid is None:
            raise TypeError("simulate_characteristic() missing required argument: 'service_uuid'")
        if characteristic_uuid is None:
            raise TypeError("simulate_characteristic() missing required argument: 'characteristic_uuid'")
        if type is None:
            raise TypeError("simulate_characteristic() missing required argument: 'type'")

        params = {
            "context": context,
            "address": address,
            "serviceUuid": service_uuid,
            "characteristicUuid": characteristic_uuid,
            "characteristicProperties": characteristic_properties,
            "type": type,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateCharacteristic", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_characteristic_response(
        self,
        context: Any | None = None,
        address: Any | None = None,
        service_uuid: Any | None = None,
        characteristic_uuid: Any | None = None,
        type: Any | None = None,
        code: int | None = None,
        data: list[Any] | None = None,
    ):
        """
        Respond to a pending read or write on a simulated characteristic.

        Args:
            context: The browsing context ID.
            address: The peripheral address.
            service: The service UUID.
            characteristic: The characteristic UUID.
            code: ATT error code (0 = success).
            body: The characteristic value bytes (for reads).
        """
        if context is None:
            raise TypeError("simulate_characteristic_response() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_characteristic_response() missing required argument: 'address'")
        if service_uuid is None:
            raise TypeError("simulate_characteristic_response() missing required argument: 'service_uuid'")
        if characteristic_uuid is None:
            raise TypeError("simulate_characteristic_response() missing required argument: 'characteristic_uuid'")
        if type is None:
            raise TypeError("simulate_characteristic_response() missing required argument: 'type'")
        if code is None:
            raise TypeError("simulate_characteristic_response() missing required argument: 'code'")

        params = {
            "context": context,
            "address": address,
            "serviceUuid": service_uuid,
            "characteristicUuid": characteristic_uuid,
            "type": type,
            "code": code,
            "data": data,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateCharacteristicResponse", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_descriptor(
        self,
        context: Any | None = None,
        address: Any | None = None,
        service_uuid: Any | None = None,
        characteristic_uuid: Any | None = None,
        descriptor_uuid: Any | None = None,
        type: Any | None = None,
    ):
        """
        Add a simulated GATT descriptor to a characteristic.

        Args:
            context: The browsing context ID.
            address: The peripheral address.
            service: The service UUID.
            characteristic: The characteristic UUID.
            descriptor: The descriptor UUID.
        """
        if context is None:
            raise TypeError("simulate_descriptor() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_descriptor() missing required argument: 'address'")
        if service_uuid is None:
            raise TypeError("simulate_descriptor() missing required argument: 'service_uuid'")
        if characteristic_uuid is None:
            raise TypeError("simulate_descriptor() missing required argument: 'characteristic_uuid'")
        if descriptor_uuid is None:
            raise TypeError("simulate_descriptor() missing required argument: 'descriptor_uuid'")
        if type is None:
            raise TypeError("simulate_descriptor() missing required argument: 'type'")

        params = {
            "context": context,
            "address": address,
            "serviceUuid": service_uuid,
            "characteristicUuid": characteristic_uuid,
            "descriptorUuid": descriptor_uuid,
            "type": type,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateDescriptor", params)
        result = self._conn.execute(cmd)
        return result

    def simulate_descriptor_response(
        self,
        context: Any | None = None,
        address: Any | None = None,
        service_uuid: Any | None = None,
        characteristic_uuid: Any | None = None,
        descriptor_uuid: Any | None = None,
        type: Any | None = None,
        code: int | None = None,
        data: list[Any] | None = None,
    ):
        """
        Respond to a pending read or write on a simulated descriptor.

        Args:
            context: The browsing context ID.
            address: The peripheral address.
            service: The service UUID.
            characteristic: The characteristic UUID.
            descriptor: The descriptor UUID.
            code: ATT error code (0 = success).
            body: The descriptor value bytes (for reads).
        """
        if context is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'context'")
        if address is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'address'")
        if service_uuid is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'service_uuid'")
        if characteristic_uuid is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'characteristic_uuid'")
        if descriptor_uuid is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'descriptor_uuid'")
        if type is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'type'")
        if code is None:
            raise TypeError("simulate_descriptor_response() missing required argument: 'code'")

        params = {
            "context": context,
            "address": address,
            "serviceUuid": service_uuid,
            "characteristicUuid": characteristic_uuid,
            "descriptorUuid": descriptor_uuid,
            "type": type,
            "code": code,
            "data": data,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.simulateDescriptorResponse", params)
        result = self._conn.execute(cmd)
        return result

    def characteristic_event_generated(
        self,
        context: Any | None = None,
        address: Any | None = None,
        service_uuid: Any | None = None,
        characteristic_uuid: Any | None = None,
        type: Any | None = None,
        data: list[Any] | None = None,
    ):
        """Execute bluetooth.characteristicEventGenerated"""
        if context is None:
            raise TypeError("characteristic_event_generated() missing required argument: 'context'")
        if address is None:
            raise TypeError("characteristic_event_generated() missing required argument: 'address'")
        if service_uuid is None:
            raise TypeError("characteristic_event_generated() missing required argument: 'service_uuid'")
        if characteristic_uuid is None:
            raise TypeError("characteristic_event_generated() missing required argument: 'characteristic_uuid'")
        if type is None:
            raise TypeError("characteristic_event_generated() missing required argument: 'type'")

        params = {
            "context": context,
            "address": address,
            "serviceUuid": service_uuid,
            "characteristicUuid": characteristic_uuid,
            "type": type,
            "data": data,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.characteristicEventGenerated", params)
        result = self._conn.execute(cmd)
        return result

    def descriptor_event_generated(
        self,
        context: Any | None = None,
        address: Any | None = None,
        service_uuid: Any | None = None,
        characteristic_uuid: Any | None = None,
        descriptor_uuid: Any | None = None,
        type: Any | None = None,
        data: list[Any] | None = None,
    ):
        """Execute bluetooth.descriptorEventGenerated"""
        if context is None:
            raise TypeError("descriptor_event_generated() missing required argument: 'context'")
        if address is None:
            raise TypeError("descriptor_event_generated() missing required argument: 'address'")
        if service_uuid is None:
            raise TypeError("descriptor_event_generated() missing required argument: 'service_uuid'")
        if characteristic_uuid is None:
            raise TypeError("descriptor_event_generated() missing required argument: 'characteristic_uuid'")
        if descriptor_uuid is None:
            raise TypeError("descriptor_event_generated() missing required argument: 'descriptor_uuid'")
        if type is None:
            raise TypeError("descriptor_event_generated() missing required argument: 'type'")

        params = {
            "context": context,
            "address": address,
            "serviceUuid": service_uuid,
            "characteristicUuid": characteristic_uuid,
            "descriptorUuid": descriptor_uuid,
            "type": type,
            "data": data,
        }
        params = {k: v for k, v in params.items() if v is not None}
        cmd = command_builder("bluetooth.descriptorEventGenerated", params)
        result = self._conn.execute(cmd)
        return result


    def add_event_handler(self, event: str, callback: Callable, contexts: list[str] | None = None) -> int:
        """Add an event handler.

        Args:
            event: The event to subscribe to.
            callback: The callback function to execute on event.
            contexts: The context IDs to subscribe to (optional).

        Returns:
            The callback ID.
        """
        return self._event_manager.add_event_handler(event, callback, contexts)

    def remove_event_handler(self, event: str, callback_id: int) -> None:
        """Remove an event handler.

        Args:
            event: The event to unsubscribe from.
            callback_id: The callback ID.
        """
        return self._event_manager.remove_event_handler(event, callback_id)

    def clear_event_handlers(self) -> None:
        """Clear all event handlers."""
        return self._event_manager.clear_event_handlers()

# Event Info Type Aliases
# Event: bluetooth.requestDevicePromptUpdated
RequestDevicePromptUpdated = globals().get('RequestDevicePromptUpdatedParameters', dict)  # Fallback to dict if type not defined

# Event: bluetooth.gattConnectionAttempted
GattConnectionAttempted = globals().get('GattConnectionAttemptedParameters', dict)  # Fallback to dict if type not defined


# Populate EVENT_CONFIGS with event configuration mappings
_globals = globals()
Bluetooth.EVENT_CONFIGS = {
    "request_device_prompt_updated": EventConfig(
        "request_device_prompt_updated",
        "bluetooth.requestDevicePromptUpdated",
        _globals.get("RequestDevicePromptUpdated", dict) if _globals.get("RequestDevicePromptUpdated") else dict,
    ),
    "gatt_connection_attempted": EventConfig(
        "gatt_connection_attempted",
        "bluetooth.gattConnectionAttempted",
        _globals.get("GattConnectionAttempted", dict) if _globals.get("GattConnectionAttempted") else dict,
    ),
}
