"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLTActivityInterceptor = createLTActivityInterceptor;
const hotmesh_1 = require("@hotmeshio/hotmesh");
const publish_1 = require("../../lib/events/publish");
const state_1 = require("./state");
/**
 * Create an LT Activity Interceptor.
 *
 * HotMesh activity interceptors support both **before** and **after**
 * phases via the interruption/replay pattern:
 *
 * 1. First execution: before-phase runs → `next()` throws
 *    `DurableProxyError` → workflow pauses
 * 2. Second execution: before-phase replays → `next()` returns
 *    the stored activity result → after-phase runs
 *
 * Before phase:
 *   Injects the envelope's pre-resolved principal into headers
 *   so activities can read it via `Durable.activity.getContext()`.
 *   Skipped for `lt*` interceptor activities (they don't need identity).
 *
 * After phase:
 *   Inspects the activity result for a `milestones` field. If present,
 *   milestone events are published to the event registry.
 *
 * @see {@link https://hotmeshio.github.io/hotmesh | HotMesh docs}
 *      `services/durable/interceptor` — Activity Interceptor Replay Pattern
 */
function createLTActivityInterceptor(_options) {
    return {
        async execute(activityCtx, workflowCtx, next) {
            try {
                // ── Before phase ─────────────────────────────────────────
                // Inject principal into headers for non-interceptor activities.
                // The principal was resolved at the front door and travels in the envelope.
                if (!activityCtx.activityName.startsWith('lt')) {
                    const envelope = (0, state_1.extractEnvelope)(workflowCtx);
                    const principal = envelope?.lt?.principal;
                    if (principal) {
                        activityCtx.options = {
                            ...activityCtx.options,
                            headers: {
                                ...(activityCtx.options?.headers ?? {}),
                                principal,
                                scopes: envelope.lt?.scopes,
                                ...(envelope.lt?.initiatingPrincipal
                                    ? { initiatingPrincipal: envelope.lt.initiatingPrincipal }
                                    : {}),
                            },
                        };
                    }
                }
                // ── Execute the activity ─────────────────────────────────
                const result = await next();
                // ── After phase ──────────────────────────────────────────
                // (runs on replay once the stored result is available)
                // Check if the activity result includes milestones
                if (result?.milestones?.length) {
                    const workflowId = workflowCtx.get('workflowId');
                    const workflowName = workflowCtx.get('workflowName');
                    const workflowTopic = workflowCtx.get('workflowTopic');
                    const taskQueue = workflowTopic
                        ? workflowTopic.replace(new RegExp(`-${workflowName}$`), '')
                        : 'long-tail-examples';
                    await (0, publish_1.publishMilestoneEvent)({
                        source: 'activity',
                        workflowId,
                        workflowName,
                        taskQueue,
                        activityName: activityCtx.activityName,
                        milestones: result.milestones,
                        data: result.data,
                    });
                }
                return result;
            }
            catch (err) {
                if (hotmesh_1.Durable.didInterrupt(err)) {
                    throw err;
                }
                throw err;
            }
        },
    };
}
