"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.notify = exports.unregister = exports.register = exports.sendNotification = exports.getConfig = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
const env_1 = require("@things-factory/env");
const admin = require('firebase-admin');
const debug = require('debug')('things-factory:notification:fcm');
const fcmconf = env_1.config.get('notification') || {};
const { fcm, vapidKey } = fcmconf;
const { serviceAccount, appConfig, serverKey } = fcm || {};
const { subject, publicKey, privateKey } = vapidKey || {};
if (serviceAccount) {
    try {
        admin.initializeApp({
            credential: admin.credential.cert(serviceAccount)
        });
        var messaging = admin.messaging();
    }
    catch (err) {
        env_1.logger.error('incorrect notification configuration');
        env_1.logger.error(err);
    }
}
function getConfig() {
    return messaging
        ? {
            appConfig,
            vapidPublicKey: publicKey
        }
        : {};
}
exports.getConfig = getConfig;
/**
 * sendNotification
 *
 * @param receiver user.id who will receive notification
 * @param message message object to be sent
 */
async function sendNotification({ receivers, message }) {
    if (!messaging) {
        return;
    }
    notify(Object.assign({ receivers }, message));
}
exports.sendNotification = sendNotification;
async function register(user, { subscription }) {
    if (!messaging || !subscription || !user) {
        return false;
    }
    try {
        var notification_key = await getDeviceGroup(user.id);
        if (!notification_key) {
            await postDeviceGroup({
                operation: 'create',
                notification_key_name: user.id,
                registration_ids: [subscription]
            });
        }
        else {
            await postDeviceGroup({
                operation: 'add',
                notification_key_name: user.id,
                notification_key,
                registration_ids: [subscription]
            });
        }
        return true;
    }
    catch (err) {
        return;
    }
}
exports.register = register;
async function unregister(user, { subscription }) {
    if (!messaging || !subscription || !user) {
        return false;
    }
    try {
        var notification_key = await getDeviceGroup(user.id);
        if (notification_key) {
            await postDeviceGroup({
                operation: 'remove',
                notification_key_name: user.id,
                notification_key,
                registration_ids: [subscription]
            });
        }
        return true;
    }
    catch (err) {
        return;
    }
}
exports.unregister = unregister;
async function notify({ receivers, privileges, tokens, topic, title, body, data, image, actions }) {
    if (!messaging) {
        return;
    }
    // Caution: non-string attributes are not allowed in FCM payload validation
    var notification = {
        title: title || '',
        body: body || '',
        image: image || ''
    };
    if (tokens && tokens instanceof Array && tokens.length > 0) {
        if (tokens.length > 1) {
            let response = await messaging.sendMulticast({
                notification,
                data,
                tokens
            });
            debug('send-all', response);
        }
        else {
            let token = tokens[0];
            let response = await messaging.send({
                notification,
                data,
                token
            });
            debug('send', response);
        }
    }
    if (topic) {
        debug('send to topic', topic);
        let response = await messaging.send({
            notification,
            data,
            topic
        });
        debug('send-topic', response);
    }
    if (receivers && receivers instanceof Array) {
        debug('send to receivers', receivers);
        for (let receiver of receivers) {
            var notification_key = await getDeviceGroup(receiver);
            if (notification_key) {
                await messaging.sendToDeviceGroup(notification_key, {
                    notification,
                    data
                });
            }
        }
    }
}
exports.notify = notify;
async function postDeviceGroup(body) {
    var response = await (0, node_fetch_1.default)('https://fcm.googleapis.com/fcm/notification', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            Authorization: `key=${serverKey}`,
            project_id: appConfig.messagingSenderId
        },
        body: JSON.stringify(body)
    });
    if (response.ok) {
        const { notification_key } = await response.json();
        return notification_key;
    }
    else {
        debug('postDeviceGroup-notok', response.status, await response.text());
    }
}
async function getDeviceGroup(notificationKeyName) {
    var response = await (0, node_fetch_1.default)(`https://fcm.googleapis.com/fcm/notification?notification_key_name=${notificationKeyName}`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            Authorization: `key=${serverKey}`,
            project_id: appConfig.messagingSenderId
        }
    });
    if (response.ok) {
        const { notification_key } = await response.json();
        return notification_key;
    }
}
//# sourceMappingURL=fcm.js.map