/**
 * Copyright 2024 Google LLC.
 * Copyright (c) Microsoft Corporation.
 *
 * 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.
 */
import { InvalidArgumentException, } from '../../../protocol/protocol.js';
export class BluetoothProcessor {
    #eventManager;
    #browsingContextStorage;
    constructor(eventManager, browsingContextStorage) {
        this.#eventManager = eventManager;
        this.#browsingContextStorage = browsingContextStorage;
    }
    async simulateAdapter(params) {
        if (params.state === undefined) {
            // The bluetooth.simulateAdapter Command
            // Step 4.2. If params["state"] does not exist, return error with error code invalid argument.
            // https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateAdapter-command
            throw new InvalidArgumentException(`Parameter "state" is required for creating a Bluetooth adapter`);
        }
        const context = this.#browsingContextStorage.getContext(params.context);
        // Bluetooth spec requires overriding the existing adapter (step 6). From the CDP
        // perspective, we need to disable the emulation first.
        // https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateAdapter-command
        await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.disable');
        await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.enable', {
            state: params.state,
            leSupported: params.leSupported ?? true,
        });
        return {};
    }
    async disableSimulation(params) {
        const context = this.#browsingContextStorage.getContext(params.context);
        await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.disable');
        return {};
    }
    async simulatePreconnectedPeripheral(params) {
        const context = this.#browsingContextStorage.getContext(params.context);
        await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulatePreconnectedPeripheral', {
            address: params.address,
            name: params.name,
            knownServiceUuids: params.knownServiceUuids,
            manufacturerData: params.manufacturerData,
        });
        return {};
    }
    async simulateAdvertisement(params) {
        const context = this.#browsingContextStorage.getContext(params.context);
        await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateAdvertisement', {
            entry: params.scanEntry,
        });
        return {};
    }
    async simulateGattConnectionResponse(params) {
        const context = this.#browsingContextStorage.getContext(params.context);
        await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateGATTOperationResponse', {
            address: params.address,
            type: 'connection',
            code: params.code,
        });
        return {};
    }
    onCdpTargetCreated(cdpTarget) {
        cdpTarget.cdpClient.on('DeviceAccess.deviceRequestPrompted', (event) => {
            this.#eventManager.registerEvent({
                type: 'event',
                method: 'bluetooth.requestDevicePromptUpdated',
                params: {
                    context: cdpTarget.id,
                    prompt: event.id,
                    devices: event.devices,
                },
            }, cdpTarget.id);
        });
        cdpTarget.browserCdpClient.on('BluetoothEmulation.gattOperationReceived', (event) => {
            if (event.type !== 'connection') {
                return;
            }
            this.#eventManager.registerEvent({
                type: 'event',
                method: 'bluetooth.gattConnectionAttempted',
                params: {
                    context: cdpTarget.id,
                    address: event.address,
                },
            }, cdpTarget.id);
        });
    }
    async handleRequestDevicePrompt(params) {
        const context = this.#browsingContextStorage.getContext(params.context);
        if (params.accept) {
            await context.cdpTarget.cdpClient.sendCommand('DeviceAccess.selectPrompt', {
                id: params.prompt,
                deviceId: params.device,
            });
        }
        else {
            await context.cdpTarget.cdpClient.sendCommand('DeviceAccess.cancelPrompt', {
                id: params.prompt,
            });
        }
        return {};
    }
}
//# sourceMappingURL=BluetoothProcessor.js.map