"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkCollectionCompletion = void 0;
const utils_1 = require("@streamr/utils");
const rxjs_1 = require("rxjs");
const handlePropagatedMessages_1 = require("./handlePropagatedMessages");
const utils_2 = require("./utils");
function checkCollectionCompletion({ expectedNodes$, propagates$, request$, responses$, }) {
    // We're done collecting when:
    // - We have the primary node's response, with publisherId
    // - We have messages from secondary nodes that are missing from the primary node
    // - We have propagates from these secondary nodes that have the missing messages
    // - We have all the responses from all the nodes that are expected to respond
    const primaryNodeResponse$ = (0, rxjs_1.combineLatest)({
        responses: responses$,
        request: request$,
    }).pipe((0, rxjs_1.map)(({ request, responses }) => responses.find((response) => response.message.requestPublisherId === request.metadata.publisherId)), 
    // only one will serve, no need to keep subscribed
    (0, rxjs_1.first)(Boolean), (0, utils_2.rethrowErrorWithSourceActionName)(`getting primary node response`));
    const secondaryNodeResponses$ = (0, rxjs_1.combineLatest)({
        responses: responses$,
        request: request$,
    }).pipe((0, rxjs_1.map)(({ request, responses }) => responses.filter((response) => response.message.requestPublisherId !== request.metadata.publisherId)));
    const gotResponseFromAllNodes$ = (0, rxjs_1.combineLatest)({
        responses: responses$,
        expectedNodes: expectedNodes$,
    }).pipe((0, rxjs_1.map)(({ responses, expectedNodes }) => {
        const responseNodes = responses.map((response) => response.metadata.publisherId);
        return expectedNodes.every((expectedNode) => responseNodes.includes((0, utils_1.toEthereumAddress)(expectedNode)));
    }), (0, rxjs_1.filter)(Boolean));
    const expectedPropagates$ = (0, rxjs_1.combineLatest)({
        secondaryNodeResponses: secondaryNodeResponses$,
        primaryNodeResponse: primaryNodeResponse$,
    }).pipe((0, rxjs_1.map)(handlePropagatedMessages_1.getExpectedPropagatedMessages));
    const missingPropagates$ = (0, rxjs_1.combineLatest)({
        expectedPropagatedMessages: expectedPropagates$,
        propagates: propagates$,
    }).pipe((0, rxjs_1.map)(handlePropagatedMessages_1.getMissingPropagatedMessages));
    const gotAllPropagates$ = missingPropagates$.pipe((0, rxjs_1.map)((missingPropagates) => missingPropagates.length === 0));
    const allDone$ = gotResponseFromAllNodes$.pipe(
    // we're executing in order to short-circuit the process
    (0, rxjs_1.switchMap)(() => gotAllPropagates$), (0, rxjs_1.first)(Boolean), (0, utils_2.rethrowErrorWithSourceActionName)(`checking collection completion`));
    return allDone$;
}
exports.checkCollectionCompletion = checkCollectionCompletion;
//# sourceMappingURL=checkCollectionCompletion.js.map