import { pid } from 'node:process';
import { assert } from "../../../shared/src/asserts.js";
import { must } from "../../../shared/src/must.js";
import * as v from "../../../shared/src/valita.js";
import { getNormalizedZeroConfig } from "../config/zero-config.js";
import { initEventSink } from "../observability/events.js";
import { ChangeStreamerHttpClient } from "../services/change-streamer/change-streamer-http.js";
import { exitAfter, runUntilKilled } from "../services/life-cycle.js";
import { ReplicatorService, } from "../services/replicator/replicator.js";
import { parentWorker, singleProcessMode, } from "../types/processes.js";
import { getShardConfig } from "../types/shards.js";
import { replicaFileModeSchema, setUpMessageHandlers, setupReplica, } from "../workers/replicator.js";
import { createLogContext } from "./logging.js";
export default async function runWorker(parent, env, ...args) {
    assert(args.length > 0, `replicator mode not specified`);
    const fileMode = v.parse(args[0], replicaFileModeSchema);
    const config = getNormalizedZeroConfig({ env, argv: args.slice(1) });
    const mode = fileMode === 'backup' ? 'backup' : 'serving';
    const workerName = `${mode}-replicator`;
    const lc = createLogContext(config, { worker: workerName });
    initEventSink(lc, config);
    const replica = await setupReplica(lc, fileMode, config.replica);
    const runningLocalChangeStreamer = config.changeStreamer.mode === 'dedicated' && !config.changeStreamer.uri;
    const shard = getShardConfig(config);
    const { taskID, change, changeStreamer: { port, uri: changeStreamerURI = runningLocalChangeStreamer
        ? `http://localhost:${port}/`
        : undefined, }, } = config;
    const changeStreamer = new ChangeStreamerHttpClient(lc, shard, change.db, changeStreamerURI);
    const replicator = new ReplicatorService(lc, taskID, `${workerName}-${pid}`, mode, changeStreamer, replica, runningLocalChangeStreamer);
    setUpMessageHandlers(lc, replicator, parent);
    const running = runUntilKilled(lc, parent, replicator);
    // Signal readiness once the first ReplicaVersionReady notification is received.
    for await (const _ of replicator.subscribe()) {
        parent.send(['ready', { ready: true }]);
        break;
    }
    return running;
}
// fork()
if (!singleProcessMode()) {
    void exitAfter(() => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)));
}
//# sourceMappingURL=replicator.js.map