/**
 * Hooks adapter — barrel.
 *
 * In-process host surface over `kernel.run.*` and selected engine services.
 * Consumers should import from this module:
 *
 *   import { Hooks, createHooks } from '../../adapters/hooks/index.js';
 *
 *   const hooks = createHooks({ repoRoot, memory, runtimeHealth });
 *   await hooks.context.init();
 *   const pack = await hooks.context.compile({ runId, host: 'cli', ... });
 *
 * The statically-exported `Hooks` namespace is a convenience for hosts that
 * don't need multi-repo isolation — it uses kernel singletons rooted at
 * process.cwd(). `createHooks()` returns a composed surface bound to the
 * supplied `ctx.repoRoot` so hosts that manage multiple repos can isolate
 * reads and mutations to the right working tree.
 */
import * as path from 'node:path';
import { ContextHooks } from './context.js';
import { ExecutionHooks } from './execution.js';
import { createHealthHooks } from './health.js';
import { createMemoryHooks } from './memory.js';
import { KernelExecutionServiceImpl, } from '../../kernel/execution/index.js';
/**
 * Stateless hooks that don't need a HooksContext.
 * - Context + Execution delegate directly to kernel singletons rooted at
 *   process.cwd(). Use `createHooks()` for multi-repo hosts.
 */
export const Hooks = {
    context: ContextHooks,
    execution: ExecutionHooks,
};
function resolveAgainst(repoRoot, p) {
    return path.isAbsolute(p) ? p : path.resolve(repoRoot, p);
}
function bindContext(repoRoot) {
    return {
        init() {
            return ContextHooks.init();
        },
        compile(request) {
            // Rewrite relative file paths against the host-owned repoRoot so
            // the kernel's process.cwd()-based resolver can't drift onto the
            // wrong working tree.
            const rewritten = {
                ...request,
                files: request.files.map((f) => resolveAgainst(repoRoot, f)),
                fileBoosts: request.fileBoosts
                    ? Object.fromEntries(Object.entries(request.fileBoosts).map(([k, v]) => [resolveAgainst(repoRoot, k), v]))
                    : undefined,
            };
            return ContextHooks.compile(rewritten);
        },
        hypertuneMax(task, files, graphConnectivity) {
            const rewritten = files.map((f) => ({ ...f, path: resolveAgainst(repoRoot, f.path) }));
            return ContextHooks.hypertuneMax(task, rewritten, graphConnectivity);
        },
        differential(prev, curr) {
            const rewritten = curr.map((f) => ({ ...f, path: resolveAgainst(repoRoot, f.path) }));
            return ContextHooks.differential(prev, rewritten);
        },
        loadLatestSessionSummary() {
            return ContextHooks.loadLatestSessionSummary();
        },
        allocateBudget(workers, totalBudget) {
            return ContextHooks.allocateBudget(workers, totalBudget);
        },
    };
}
function bindExecution(repoRoot) {
    // Dedicated service bound to this repoRoot — does NOT touch the process
    // singleton, so concurrent createHooks({ repoRoot: A }) and createHooks({
    // repoRoot: B }) both land on their own working tree.
    const service = new KernelExecutionServiceImpl({ repoRoot });
    return {
        step(request) {
            return service.step(request);
        },
        verify(request) {
            return service.verify(request);
        },
        merge(request) {
            return service.merge(request);
        },
        execute(request) {
            return service.execute(request);
        },
    };
}
/**
 * Compose a fully-wired hooks namespace for a host that has memory + runtime
 * providers. Throws at construction time if required providers are missing —
 * fail-fast contract so hosts catch wiring errors early.
 *
 * Context + execution are bound to `ctx.repoRoot`:
 * - context.compile / hypertuneMax / differential pre-resolve relative paths
 *   against repoRoot before calling the kernel.
 * - execution uses a dedicated KernelExecutionServiceImpl rooted at repoRoot;
 *   the process-wide kernel singleton is left untouched.
 */
export function createHooks(ctx) {
    if (!ctx.repoRoot || !path.isAbsolute(ctx.repoRoot)) {
        throw new Error('createHooks: ctx.repoRoot must be an absolute path');
    }
    if (!ctx.memory)
        throw new Error('createHooks: ctx.memory is required');
    if (!ctx.runtimeHealth)
        throw new Error('createHooks: ctx.runtimeHealth is required');
    return {
        context: bindContext(ctx.repoRoot),
        execution: bindExecution(ctx.repoRoot),
        health: createHealthHooks(ctx.runtimeHealth),
        memory: createMemoryHooks(ctx.memory),
    };
}
export { ContextHooks } from './context.js';
export { ExecutionHooks } from './execution.js';
