import fs from 'fs';
import path from 'path';
import { resolveWorkspaceStateRoot } from './workspace-resolver.js';
import { resolveArchitectsPaths } from '../architects/db/client.js';
import { resolveSynapsePaths } from '../synapse/db/client.js';
function ensureWritableDirectory(target) {
    fs.mkdirSync(target, { recursive: true });
    fs.accessSync(target, fs.constants.W_OK);
}
function remediationForEngine(name) {
    return [
        `Verify the ${name} state root is writable.`,
        'Ensure better-sqlite3 is installed and compiled for this host.',
        `Run \`nexus-prime setup runtime ${name}\` if the runtime files were never provisioned.`,
    ];
}
function resolveEngineDbPath(name, root) {
    return name === 'synapse'
        ? resolveSynapsePaths(root).dbPath
        : resolveArchitectsPaths(root).dbPath;
}
function planEngineStorage(name, workspaceRoot, stateRoot) {
    const requestedStorageRoot = workspaceRoot;
    const requestedDbPath = resolveEngineDbPath(name, requestedStorageRoot);
    try {
        ensureWritableDirectory(path.dirname(requestedDbPath));
        return {
            name,
            required: true,
            requestedStorageRoot,
            activeStorageRoot: requestedStorageRoot,
            dbPath: requestedDbPath,
            fallbackApplied: false,
            ready: true,
            state: 'ready',
            remediation: remediationForEngine(name),
        };
    }
    catch (error) {
        const fallbackReason = error instanceof Error ? error.message : String(error);
        const fallbackDbPath = resolveEngineDbPath(name, stateRoot);
        try {
            ensureWritableDirectory(path.dirname(fallbackDbPath));
            return {
                name,
                required: true,
                requestedStorageRoot,
                activeStorageRoot: stateRoot,
                dbPath: fallbackDbPath,
                fallbackApplied: true,
                fallbackReason,
                ready: true,
                state: 'fallback',
                remediation: remediationForEngine(name),
            };
        }
        catch (fallbackError) {
            const blockedReason = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
            return {
                name,
                required: true,
                requestedStorageRoot,
                activeStorageRoot: stateRoot,
                dbPath: fallbackDbPath,
                fallbackApplied: true,
                fallbackReason: `${fallbackReason}; fallback failed: ${blockedReason}`,
                ready: false,
                state: 'blocked',
                remediation: remediationForEngine(name),
            };
        }
    }
}
export function resolveMandatoryRuntimePlan(workspace) {
    const requestedRoot = workspace.gitRoot ?? workspace.workspaceRoot;
    const stateRoot = resolveWorkspaceStateRoot(requestedRoot);
    const synapse = planEngineStorage('synapse', workspace.workspaceRoot, stateRoot);
    const architects = planEngineStorage('architects', workspace.workspaceRoot, stateRoot);
    const reasons = [synapse, architects]
        .filter((engine) => !engine.ready || engine.fallbackApplied)
        .map((engine) => `${engine.name}:${engine.state}${engine.fallbackReason ? ` (${engine.fallbackReason})` : ''}`);
    const hasBlocked = [synapse, architects].some((engine) => !engine.ready);
    const hasFallback = [synapse, architects].some((engine) => engine.fallbackApplied);
    return {
        schemaVersion: 1,
        workspace: {
            ...workspace,
            stateRoot,
        },
        engines: {
            synapse,
            architects,
        },
        readiness: {
            status: hasBlocked ? 'blocked' : hasFallback ? 'degraded' : 'ready',
            reasons,
        },
    };
}
export function finalizeRuntimeHealthEnvelope(envelope, readiness) {
    const engines = {
        synapse: { ...envelope.engines.synapse },
        architects: { ...envelope.engines.architects },
    };
    Object.keys(readiness).forEach((name) => {
        const result = readiness[name];
        if (!result)
            return;
        engines[name].ready = result.ready;
        if (!result.ready) {
            engines[name].state = 'blocked';
            engines[name].fallbackReason = result.error ?? engines[name].fallbackReason;
        }
        else if (engines[name].fallbackApplied) {
            engines[name].state = 'fallback';
        }
        else {
            engines[name].state = 'ready';
        }
    });
    const reasons = [engines.synapse, engines.architects]
        .filter((engine) => !engine.ready || engine.fallbackApplied)
        .map((engine) => `${engine.name}:${engine.state}${engine.fallbackReason ? ` (${engine.fallbackReason})` : ''}`);
    return {
        ...envelope,
        engines,
        readiness: {
            status: reasons.some((reason) => reason.includes(':blocked'))
                ? 'blocked'
                : reasons.length > 0
                    ? 'degraded'
                    : 'ready',
            reasons,
        },
    };
}
