"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.acquireSequencePropsSubscription = void 0;
const studio_shared_1 = require("@remotion/studio-shared");
const remotion_1 = require("remotion");
const call_api_1 = require("../call-api");
const makeKey = ({ fileName, line, column, componentIdentity, sequenceKeys, effectKeys, videoConfigValues, }) => `${fileName}\0${line}\0${column}\0${componentIdentity !== null && componentIdentity !== void 0 ? componentIdentity : ''}\0${sequenceKeys.join('\0')}\0${effectKeys.map((keys) => keys.join('\0')).join('\0\0')}\0${JSON.stringify(videoConfigValues)}`;
const entries = new Map();
const acquireSequencePropsSubscription = ({ fileName, line, column, schema, componentIdentity, effects, nodePath, clientId, applyOnce, applyEach, videoConfigValues, }) => {
    const sequenceKeys = (0, studio_shared_1.getAllSchemaKeys)(schema);
    const effectKeys = effects.map((effect) => (0, studio_shared_1.getAllSchemaKeys)(effect));
    const key = makeKey({
        fileName,
        line,
        column,
        componentIdentity,
        sequenceKeys,
        effectKeys,
        videoConfigValues,
    });
    let entry = entries.get(key);
    if (!entry) {
        const promise = (0, call_api_1.callApi)('/api/subscribe-to-sequence-props', {
            fileName,
            line,
            column,
            nodePath,
            componentIdentity,
            keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
            effects: effectKeys,
            clientId,
            videoConfigValues,
        });
        const created = {
            refCount: 0,
            promise,
            fileName,
            clientId,
            applyOnce,
        };
        entries.set(key, created);
        entry = created;
        promise
            .then((result) => {
            const current = entries.get(key);
            if (current !== created || !current.applyOnce) {
                return;
            }
            const cb = current.applyOnce;
            current.applyOnce = null;
            cb(result);
        })
            .catch((err) => {
            const current = entries.get(key);
            if (current !== created) {
                return;
            }
            current.applyOnce = null;
            remotion_1.Internals.Log.error(err);
        });
    }
    entry.refCount++;
    const acquired = entry;
    acquired.promise.then(applyEach).catch(() => {
        // Error already logged by the first acquirer.
    });
    let released = false;
    return {
        release: () => {
            if (released) {
                return;
            }
            released = true;
            acquired.refCount--;
            if (acquired.refCount > 0) {
                return;
            }
            if (entries.get(key) === acquired) {
                entries.delete(key);
            }
            acquired.promise
                .then((result) => {
                if (!result.success) {
                    return;
                }
                return (0, call_api_1.callApi)('/api/unsubscribe-from-sequence-props', {
                    fileName: acquired.fileName,
                    nodePath: result.nodePath,
                    clientId: acquired.clientId,
                    sequenceKeys,
                    effectKeys,
                });
            })
                .catch(() => {
                // Ignore — either the subscribe failed (nothing to clean up) or
                // the unsubscribe failed (server-side TTL will handle it).
            });
        },
    };
};
exports.acquireSequencePropsSubscription = acquireSequencePropsSubscription;
