import io from 'socket.io-client';
import { recorderEventBus } from '../eventBus';
import messagingService from '../services/messaging.service';
import { SESSION_ADD_EVENT, SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, SESSION_SUBSCRIBE_EVENT, SESSION_UNSUBSCRIBE_EVENT, } from '../config';
const MAX_RECONNECTION_ATTEMPTS = 2;
export class RrwebEventExporter {
    constructor(options) {
        this.options = options;
        this.socket = null;
        this.queue = [];
        this.isConnecting = false;
        this.isConnected = false;
        this.usePostMessage = false;
        this.attempts = 0;
        this.sessionId = null;
    }
    init() {
        if (this.isConnecting || this.isConnected)
            return;
        this.attempts++;
        this.isConnecting = true;
        this.usePostMessage = false;
        this.socket = io(this.options.socketUrl, {
            path: '/v0/radar/ws',
            auth: {
                'x-api-key': this.options.apiKey,
            },
            reconnectionAttempts: 2,
            transports: ['websocket'],
        });
        // this.socket.on('connect', () => {
        //   this.isConnecting = false
        //   this.isConnected = true
        //   this.usePostMessage = false
        //   this.flushQueue()
        // })
        this.socket.on('ready', () => {
            this.isConnecting = false;
            this.isConnected = true;
            this.usePostMessage = false;
            this.flushQueue();
        });
        this.socket.on('disconnect', (err) => {
            this.isConnecting = false;
            this.isConnected = false;
        });
        this.socket.on('connect_error', (err) => {
            this.isConnecting = false;
            this.isConnected = false;
            this.checkReconnectionAttempts();
        });
        this.socket.on(SESSION_STOPPED_EVENT, (data) => {
            recorderEventBus.emit(SESSION_STOPPED_EVENT, data);
            this.unsubscribeFromSession();
        });
        this.socket.on(SESSION_AUTO_CREATED, (data) => {
            recorderEventBus.emit(SESSION_AUTO_CREATED, data);
        });
    }
    checkReconnectionAttempts() {
        if (this.attempts >= MAX_RECONNECTION_ATTEMPTS) {
            this.usePostMessage = !!this.options.usePostMessageFallback;
            this.flushQueue();
        }
    }
    sendViaPostMessage(event) {
        messagingService.sendMessage('rrweb-event', event);
    }
    flushQueue() {
        var _a, _b;
        while (this.queue.length > 0 && (this.usePostMessage || ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected))) {
            const event = this.queue.shift();
            if (!event)
                continue;
            if (this.usePostMessage) {
                this.sendViaPostMessage(event.data);
            }
            else if ((_b = this.socket) === null || _b === void 0 ? void 0 : _b.connected) {
                this.socket.emit(event.name, event.data);
            }
        }
    }
    unsubscribeFromSession() {
        var _a;
        const payload = {
            debugSessionId: this.sessionId,
        };
        if (this.usePostMessage) {
            messagingService.sendMessage('socket-emit', { event: SESSION_UNSUBSCRIBE_EVENT, data: payload });
        }
        else if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) {
            this.socket.emit(SESSION_UNSUBSCRIBE_EVENT, payload);
        }
    }
    send(event) {
        var _a;
        if (this.usePostMessage) {
            this.sendViaPostMessage(event);
        }
        else if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) {
            this.socket.emit(SESSION_ADD_EVENT, event);
        }
        else {
            this.queue.push({ data: event, name: SESSION_ADD_EVENT });
            this.init();
        }
    }
    subscribeToSession(session) {
        var _a;
        this.sessionId = session.shortId || session._id;
        const payload = {
            projectId: session.project,
            workspaceId: session.workspace,
            debugSessionId: this.sessionId,
            sessionType: session.creationType,
        };
        if (this.usePostMessage) {
            this.sendViaPostMessage({ type: SESSION_SUBSCRIBE_EVENT, ...payload });
        }
        else if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) {
            this.socket.emit(SESSION_SUBSCRIBE_EVENT, payload);
        }
        else {
            this.queue.push({ data: payload, name: SESSION_SUBSCRIBE_EVENT });
            this.init();
        }
    }
    close() {
        var _a;
        if (this.usePostMessage) {
            this.sendViaPostMessage({ type: 'close' });
        }
        if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) {
            setTimeout(() => {
                var _a;
                this.unsubscribeFromSession();
                this.attempts = 0;
                this.isConnected = false;
                this.isConnecting = false;
                (_a = this.socket) === null || _a === void 0 ? void 0 : _a.disconnect();
                this.socket = null;
            }, 500);
        }
    }
}
//# sourceMappingURL=exporter.js.map