// This Source Code Form is subject to the terms of the Mozilla Public
// License, v2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/
import { recordToDataView } from "../../utils/encoding";
import { FoxgloveCommunicator, } from "../communicator";
import { makeServiceCallRequest } from "../foxglove-protocol";
export class WebRtcHandler extends FoxgloveCommunicator {
    #subscriptionId = 0;
    #messageReady = false;
    #systemReady = false;
    #subscriptions = new Map();
    isReady() {
        return this.#messageReady && this.#systemReady;
    }
    send(message) {
        self.postMessage(message);
    }
    sendWithTransfer(message, transfer) {
        self.postMessage(message, transfer);
    }
    #rawSubscribe(channelId) {
        const subscriptionId = ++this.#subscriptionId;
        const subscriptions = [{
                id: subscriptionId,
                channelId,
            }];
        self.postMessage({
            type: "send",
            data: {
                channel: "system",
                data: recordToDataView({
                    op: "subscribe",
                    subscriptions,
                }),
            },
        });
        return subscriptionId;
    }
    subscribe(topics) {
        const channels = this.getPublicChannels().filter(publicChannel => topics.includes(publicChannel.topic));
        for (const channel of channels) {
            const subscription = this.#rawSubscribe(channel.id);
            this.#subscriptions.set(subscription, {
                topic: channel.topic,
                schema: channel.schemaName,
                kind: channel.kind
            });
        }
    }
    #rawUnsubscribe(subscriptionId) {
        self.postMessage({
            type: "send",
            data: {
                channel: "system",
                data: recordToDataView({
                    op: "unsubscribe",
                    subscriptionIds: [subscriptionId],
                }),
            },
        });
    }
    unsubscribe(topics) {
        const subscriptionIds = [...this.#subscriptions.entries()].filter(([_id, data]) => topics.includes(data.topic)).map(subscription => subscription[0]);
        for (const subscriptionId of subscriptionIds) {
            this.#subscriptions.delete(subscriptionId);
            this.#rawUnsubscribe(subscriptionId);
        }
    }
    sendServiceCallRequest(args) {
        const data = makeServiceCallRequest(args);
        self.postMessage({
            type: "send",
            data: { channel: "message", data },
        }, [data.buffer]);
    }
    handleRawSend(data) {
        self.postMessage({
            type: "send",
            data,
        });
    }
    handleConnection(data) {
        if (!data.channel || data.channel === "message") {
            this.#messageReady = data.ready;
        }
        if (!data.channel || data.channel === "system") {
            this.#systemReady = data.ready;
        }
    }
    handleGeneric(message) {
        const subscription = this.#subscriptions.get(message.subscriptionId);
        if (subscription) {
            this.handleGenericMessage(subscription.topic, subscription.schema, message.data);
        }
    }
    handleDisconnect(error) {
        this.send({ type: "disconnect", error });
    }
    handleServiceCall(message) {
        this.callService(message);
    }
    handleSystem(message) {
        switch (message.op) {
            case "advertise": {
                this.handleChannelsAdvertisement(message.channels);
                break;
            }
            case "unadvertise": {
                this.handleChannelsUnadvertisement(message.channelIds);
                break;
            }
            case "advertiseServices": {
                this.handleServicesAdvertisement(message.services);
                break;
            }
            case "unadvertiseServices": {
                this.handleServicesUnadvertisement(message.serviceIds);
                break;
            }
            case "serviceResponse": {
                this.handleServiceResponse(message);
                break;
            }
        }
    }
}
//# sourceMappingURL=handler.js.map