import { ModuleRef } from '@nestjs/core';
import { JobRunRow } from './job-orchestration.schema.js';
import { I as IJobOrchestrator, g as JobHandlerMeta, f as JobHandlerBase, j as JobUpsertEntry, h as JobPoolDef, l as StartOptions, i as JobRun, C as CancelOptions } from '../../../job-orchestrator.protocol-DubMVbm9.js';
import { MemoryJobStore } from './memory-job-store.js';
import { MemoryJobStepService } from './job-step-service.memory-backend.js';
import 'drizzle-orm/pg-core';
import 'drizzle-orm';
import '../events/event-bus.protocol.js';
import '../../types/drizzle.js';
import 'drizzle-orm/node-postgres';
import '@nestjs/common';
import '../events/event-registry.js';
import './job-step-service.protocol.js';

/** Handler registry entry — class + frozen metadata. */
interface HandlerRegistration {
    type: string;
    meta: JobHandlerMeta<unknown>;
    handlerClass: new (...args: unknown[]) => JobHandlerBase<unknown>;
}
declare class MemoryJobOrchestrator implements IJobOrchestrator {
    private readonly store;
    private readonly stepService;
    private readonly multiTenant;
    private readonly moduleRef?;
    private readonly logger;
    private readonly mutex;
    private readonly handlerRegistry;
    /**
     * `runId → dependent runId[]` — when a run with `concurrencyKey = K`
     * blocks on an incumbent, its id is added here under the incumbent's id.
     * On incumbent terminal transition we advance every dependent's `runAt`
     * back to `now()` so it becomes claimable.
     */
    private readonly queueBlockers;
    constructor(store: MemoryJobStore, stepService: MemoryJobStepService, multiTenant: boolean, moduleRef?: ModuleRef | undefined);
    /**
     * JOB-8 — mirror of the Drizzle backend's `resolveTenantId`. Returns the
     * value to stamp on `tenant_id` / compare against in memory predicates.
     * Off → always `null`. On + `undefined` → throw. On + `null`/string → pass.
     */
    private resolveTenantId;
    /**
     * Populate the in-memory job definition row plus handler class lookup.
     * Called by `JobWorkerModule.onModuleInit` in memory mode, or directly by
     * unit tests that want to seed the registry without NestJS.
     */
    registerHandler<TInput>(type: string, meta: JobHandlerMeta<TInput>, handlerClass: new (...args: unknown[]) => JobHandlerBase<TInput>): void;
    /** Test helper — look up a registered handler without exposing the map. */
    getHandlerRegistration(type: string): HandlerRegistration | undefined;
    /**
     * Boot-time upsert per `IJobOrchestrator.upsertJobRows`. Memory backend
     * just funnels each entry through `registerHandler`. The validator is
     * skipped entirely in memory mode (Q4 resolution 2026-04-19), so the
     * orphaned list is always empty — there are no DB rows to compare against.
     */
    upsertJobRows(entries: JobUpsertEntry[], poolConfig: ReadonlyMap<string, JobPoolDef>): Promise<{
        orphaned: string[];
    }>;
    start(type: string, input: unknown, opts?: StartOptions, _tx?: unknown): Promise<JobRun>;
    cancel(runId: string, opts?: CancelOptions): Promise<void>;
    /**
     * Internal cancel that assumes the caller already holds the mutex.
     * Synchronous because all store ops are in-memory. Idempotent.
     *
     * `tenantForGate` is the already-validated tenant id (or `null`). When
     * non-null it gates the initial cancellation to that tenant's run; the
     * cascade step then sweeps descendants on the same `rootRunId` without
     * re-checking — children of a tenant-gated parent always share the
     * tenant (enforced at `start` time).
     */
    private cancelLocked;
    private transitionToCanceled;
    /**
     * When `runId` transitions to a terminal state, advance every dependent
     * `queue`-blocked run's `run_at` back to `now()` so `claimNext` picks
     * them up.
     */
    private unblockQueuedDependents;
    claimNext(pool: string): Promise<JobRunRow | null>;
    replay(runId: string): Promise<JobRun>;
    /**
     * Execute a single claimed run to completion, retry, or failure. Not on
     * `IJobOrchestrator` — it's the memory equivalent of the Drizzle
     * `JobWorker.processRun` code path. The unit tests drive it directly so
     * they can assert memoization across ticks without spinning up a worker.
     */
    tick(runId: string): Promise<void>;
    private makeStepFn;
    private makeSpawnFn;
    private nextStepSeq;
    private markCompleted;
    private markFailed;
    private rescheduleForRetry;
    private findDedupeCandidate;
    private findInFlightByConcurrencyKey;
}

export { MemoryJobOrchestrator };
