"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.repeatWhen = void 0;
const Observable_js_1 = require("../Observable.js");
const Subject_js_1 = require("../Subject.js");
function repeatWhen(notifier) {
    return (source) => new Observable_js_1.Observable((destination) => {
        let innerSub;
        let syncResub = false;
        let completions$;
        let isNotifierComplete = false;
        let isMainComplete = false;
        const checkComplete = () => isMainComplete && isNotifierComplete && (destination.complete(), true);
        const getCompletionSubject = () => {
            if (!completions$) {
                completions$ = new Subject_js_1.Subject();
                (0, Observable_js_1.from)(notifier(completions$)).subscribe((0, Observable_js_1.operate)({
                    destination,
                    next: () => {
                        if (innerSub) {
                            subscribeForRepeatWhen();
                        }
                        else {
                            syncResub = true;
                        }
                    },
                    complete: () => {
                        isNotifierComplete = true;
                        checkComplete();
                    },
                }));
            }
            return completions$;
        };
        const subscribeForRepeatWhen = () => {
            isMainComplete = false;
            innerSub = source.subscribe((0, Observable_js_1.operate)({
                destination,
                complete: () => {
                    isMainComplete = true;
                    !checkComplete() && getCompletionSubject().next();
                },
            }));
            if (syncResub) {
                innerSub.unsubscribe();
                innerSub = null;
                syncResub = false;
                subscribeForRepeatWhen();
            }
        };
        subscribeForRepeatWhen();
    });
}
exports.repeatWhen = repeatWhen;