"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendNotification = void 0;
const tslib_1 = require("tslib");
const axios_1 = require("axios");
const helpers_1 = require("./helpers");
const helpers_2 = require("../helpers");
const constants_1 = require("./constants");
const constants_2 = require("../constants");
const getChannel_1 = require("../channels/getChannel");
/**
 * Validate options for some scenarios
 */
function validateOptions(options) {
    var _a, _b;
    if (!(options === null || options === void 0 ? void 0 : options.channel)) {
        throw '[Push SDK] - Error - sendNotification() - "channel" is mandatory!';
    }
    if (!(0, helpers_2.isValidETHAddress)(options.channel)) {
        throw '[Push SDK] - Error - sendNotification() - "channel" is invalid!';
    }
    if (options.senderType === 0 && options.signer === undefined) {
        throw '[Push SDK] - Error - sendNotification() - "signer" is mandatory!';
    }
    if (options.senderType === 1 && options.pgpPrivateKey === undefined) {
        throw '[Push SDK] - Error - sendNotification() - "pgpPrivateKey" is mandatory!';
    }
    /**
     * Apart from IPFS, GRAPH use cases "notification", "payload" is mandatory
     */
    if ((options === null || options === void 0 ? void 0 : options.identityType) === constants_1.IDENTITY_TYPE.DIRECT_PAYLOAD ||
        (options === null || options === void 0 ? void 0 : options.identityType) === constants_1.IDENTITY_TYPE.MINIMAL) {
        if (!options.notification) {
            throw '[Push SDK] - Error - sendNotification() - "notification" mandatory for Identity Type: Direct Payload, Minimal!';
        }
        if (!options.payload) {
            throw '[Push SDK] - Error - sendNotification() - "payload" mandatory for Identity Type: Direct Payload, Minimal!';
        }
    }
    const isAdditionalMetaPayload = (_a = options.payload) === null || _a === void 0 ? void 0 : _a.additionalMeta;
    const isVideoOrSpaceType = typeof ((_b = options.payload) === null || _b === void 0 ? void 0 : _b.additionalMeta) === 'object' &&
        (options.payload.additionalMeta.type ===
            `${constants_1.VIDEO_CALL_TYPE.PUSH_VIDEO}+1` ||
            options.payload.additionalMeta.type ===
                `${constants_1.VIDEO_CALL_TYPE.PUSH_SPACE}+1`);
    if (isAdditionalMetaPayload &&
        isVideoOrSpaceType &&
        !options.chatId &&
        !options.rules) {
        throw new Error('[Push SDK] - Error - sendNotification() - Either chatId or rules object is required to send a additional meta notification for video or spaces');
    }
}
/**
 *
 * @param payloadOptions channel, recipient and type tp verify whether it is a simulate type
 * @returns boolean
 */
function checkSimulateNotification(payloadOptions) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        try {
            const { channel, recipient, type, env } = payloadOptions || {};
            // fetch channel info
            const channelInfo = yield (0, getChannel_1.getChannel)({
                channel: channel,
                env: env,
            });
            // check if channel exists, if it does then its not simulate type
            if (channelInfo)
                return false;
            else {
                // if no channel info found, check if channel address = recipient and notification type is targeted
                const convertedRecipient = typeof recipient == 'string' && (recipient === null || recipient === void 0 ? void 0 : recipient.split(':').length) == 3
                    ? recipient.split(':')[2]
                    : recipient;
                return (channel == convertedRecipient && type == constants_1.NOTIFICATION_TYPE.TARGETTED);
            }
        }
        catch (e) {
            return true;
        }
    });
}
function sendNotification(options) {
    var _a;
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        try {
            const { 
            /*
              senderType = 0 for channel notification (default)
              senderType = 1 for chat notification
            */
            senderType = 0, signer, type, identityType, payload, recipients, channel, graph, ipfsHash, env = constants_2.ENV.PROD, chatId, rules, pgpPrivateKey, } = options || {};
            validateOptions(options);
            if (payload &&
                payload.additionalMeta &&
                typeof payload.additionalMeta === 'object' &&
                !payload.additionalMeta.domain) {
                payload.additionalMeta.domain = constants_1.DEFAULT_DOMAIN;
            }
            const _channelAddress = yield (0, helpers_2.getCAIPAddress)(env, channel, 'Channel');
            const channelCAIPDetails = (0, helpers_2.getCAIPDetails)(_channelAddress);
            if (!channelCAIPDetails)
                throw Error('Invalid Channel CAIP!');
            const uuid = (0, helpers_1.getUUID)();
            const chainId = parseInt(channelCAIPDetails.networkId, 10);
            const API_BASE_URL = (0, helpers_2.getAPIBaseUrls)(env);
            let COMMUNICATOR_CONTRACT = '';
            if (senderType === 0) {
                const { EPNS_COMMUNICATOR_CONTRACT } = (0, helpers_2.getConfig)(env, channelCAIPDetails);
                COMMUNICATOR_CONTRACT = EPNS_COMMUNICATOR_CONTRACT;
            }
            const _recipients = yield (0, helpers_1.getRecipients)({
                env,
                notificationType: type,
                channel: _channelAddress,
                recipients,
                secretType: payload === null || payload === void 0 ? void 0 : payload.sectype,
            });
            const notificationPayload = (0, helpers_1.getPayloadForAPIInput)(options, _recipients);
            const verificationProof = yield (0, helpers_1.getVerificationProof)({
                senderType,
                signer,
                chainId,
                identityType,
                notificationType: type,
                verifyingContract: COMMUNICATOR_CONTRACT,
                payload: notificationPayload,
                graph,
                ipfsHash,
                uuid,
                // for the pgpv2 verfication proof
                chatId: (_a = rules === null || rules === void 0 ? void 0 : rules.access.data) !== null && _a !== void 0 ? _a : chatId,
                pgpPrivateKey,
            });
            const identity = (0, helpers_1.getPayloadIdentity)({
                identityType,
                payload: notificationPayload,
                notificationType: type,
                graph,
                ipfsHash,
            });
            const source = (yield checkSimulateNotification({
                channel: options.channel,
                recipient: options.recipients,
                type: options.type,
                env: options.env,
            }))
                ? constants_1.SOURCE_TYPES.SIMULATE
                : (0, helpers_1.getSource)(chainId, identityType, senderType);
            const apiPayload = Object.assign({ verificationProof,
                identity, sender: senderType === 1 && !(0, helpers_2.isValidCAIP10NFTAddress)(_channelAddress)
                    ? `${channelCAIPDetails === null || channelCAIPDetails === void 0 ? void 0 : channelCAIPDetails.blockchain}:${channelCAIPDetails === null || channelCAIPDetails === void 0 ? void 0 : channelCAIPDetails.address}`
                    : _channelAddress, source, 
                /** note this recipient key has a different expectation from the BE API, see the funciton for more */
                recipient: yield (0, helpers_1.getRecipientFieldForAPIPayload)({
                    env,
                    notificationType: type,
                    recipients: recipients || '',
                    channel: _channelAddress,
                }) }, (rules || chatId
                ? {
                    rules: rules !== null && rules !== void 0 ? rules : {
                        access: {
                            data: chatId,
                            type: constants_1.VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT,
                        },
                    },
                }
                : {}));
            const requestURL = `${API_BASE_URL}/v1/payloads/`;
            return yield axios_1.default.post(requestURL, apiPayload, {
                headers: {
                    'Content-Type': 'application/json',
                },
            });
        }
        catch (err) {
            console.error('[Push SDK] - Error - sendNotification() - ', JSON.stringify(err));
            throw err;
        }
    });
}
exports.sendNotification = sendNotification;
//# sourceMappingURL=sendNotifications.js.map