import { logger } from '@crosslab/service-common';
import fetch from 'node-fetch';
import { config } from '../config.js';
import { repositories } from '../database/dataSource.js';
import { deviceUrlFromId, peerconnectionUrlFromId } from './urlFromId.js';
export const callbackUrl = (config.BASE_URL + '/callbacks/device').replace('//callbacks', '/callbacks');
export const changedCallbacks = new Map();
export const closedCallbacks = new Map();
export const statusChangedCallbacks = new Map();
/**
 * This function sends a 'device-changed' callback.
 * @param device The device for which to send the callback.
 */
export async function sendChangedCallback(device) {
    const urls = changedCallbacks.get(device.uuid) ?? [];
    for (const url of urls) {
        // TODO: proper error handling
        try {
            logger.log('info', `Sending changed-callback for device '${deviceUrlFromId(device.uuid)}' to '${url}'`);
            const formattedDevice = await repositories.device.format(device);
            // TODO: handle device groups correctly
            const callback = {
                callbackType: 'event',
                eventType: 'device-changed',
                device: formattedDevice.type === 'group'
                    ? { ...formattedDevice, added: [], changed: [], removed: [] }
                    : formattedDevice,
            };
            const res = await fetch(url, {
                method: 'POST',
                body: JSON.stringify(callback),
                headers: [['Content-Type', 'application/json']],
            });
            if (res.status === 410) {
                const changedCallbackURLs = changedCallbacks.get(device.uuid);
                changedCallbacks.set(device.uuid, changedCallbackURLs?.filter(cbUrl => cbUrl != url));
            }
        }
        catch (error) {
            logger.log('error', 'An error occurred while sending a changed-callback', {
                data: { error, device: deviceUrlFromId(device.uuid), url },
            });
        }
    }
}
/**
 * This function sends a 'peerconnection-closed' callback.
 * @param peerconnection The peerconnection for which to send the callback.
 */
export async function sendClosedCallback(peerconnection) {
    const urls = closedCallbacks.get(peerconnection.uuid) ?? [];
    for (const url of urls) {
        // TODO: proper error handling
        try {
            logger.log('info', `Sending closed-callback for peerconnection '${peerconnectionUrlFromId(peerconnection.uuid)}' to '${url}'`);
            const callback = {
                callbackType: 'event',
                eventType: 'peerconnection-closed',
                peerconnection: await repositories.peerconnection.format(peerconnection),
            };
            const res = await fetch(url, {
                method: 'POST',
                body: JSON.stringify(callback),
                headers: [['Content-Type', 'application/json']],
            });
            if (res.status === 410) {
                const closedCallbackURLs = closedCallbacks.get(peerconnection.uuid);
                closedCallbacks.set(peerconnection.uuid, closedCallbackURLs?.filter(cbUrl => cbUrl != url));
            }
        }
        catch (error) {
            logger.log('error', 'An error occurred while sending a closed-callback', {
                data: {
                    error,
                    peerconnection: peerconnectionUrlFromId(peerconnection.uuid),
                    url,
                },
            });
        }
    }
}
/**
 * This function sends a 'peerconnection-status-changed' callback.
 * @param peerconnection The peerconnection for which to send the callback.
 */
export async function sendStatusChangedCallback(peerconnection) {
    const urls = statusChangedCallbacks.get(peerconnection.uuid) ?? [];
    for (const url of urls) {
        // TODO: proper error handling
        try {
            logger.log('info', `Sending status-changed-callback for peerconnection '${peerconnectionUrlFromId(peerconnection.uuid)}' to '${url}'`);
            const callback = {
                callbackType: 'event',
                eventType: 'peerconnection-status-changed',
                peerconnection: await repositories.peerconnection.format(peerconnection),
            };
            const res = await fetch(url, {
                method: 'POST',
                body: JSON.stringify(callback),
                headers: [['Content-Type', 'application/json']],
            });
            if (res.status === 410) {
                const statusCallbackURLs = statusChangedCallbacks.get(peerconnection.uuid);
                statusChangedCallbacks.set(peerconnection.uuid, statusCallbackURLs?.filter(cbUrl => cbUrl != url));
            }
        }
        catch (error) {
            logger.log('error', 'An error occurred while sending a status-changed-callback', {
                data: {
                    error,
                    peerconnection: peerconnectionUrlFromId(peerconnection.uuid),
                    url,
                },
            });
        }
    }
}
//# sourceMappingURL=callbacks.js.map