/**
 * State-Sync - Context-Diff Bridge
 *
 * Provides utilities for generating and applying deltas between
 * Bash snapshots. This is used for efficient synchronization
 * of agentic workspaces.
 */
/**
 * Generates a delta between a base snapshot and current state.
 */
export function diffState(base, current) {
    const delta = Object.create(null);
    // 1. Diff Environment Variables (Map<string, string>)
    const envDelta = Object.create(null);
    let envChanged = false;
    const baseEnv = base.state.env;
    const currEnv = current.state.env;
    // Added or modified
    for (const [key, val] of currEnv.entries()) {
        if (baseEnv.get(key) !== val) {
            envDelta[key] = val;
            envChanged = true;
        }
    }
    // Deleted
    for (const key of baseEnv.keys()) {
        if (!currEnv.has(key)) {
            envDelta[key] = null;
            envChanged = true;
        }
    }
    if (envChanged)
        delta.envDelta = envDelta;
    // 2. Diff Functions (Map<string, FunctionDefNode>)
    const funcDelta = Object.create(null);
    let funcChanged = false;
    const baseFuncs = base.state.functions;
    const currFuncs = current.state.functions;
    for (const [name, node] of currFuncs.entries()) {
        const baseNode = baseFuncs.get(name);
        if (baseNode !== node) {
            funcDelta[name] = "MODIFIED";
            funcChanged = true;
        }
    }
    for (const name of baseFuncs.keys()) {
        if (!currFuncs.has(name)) {
            funcDelta[name] = null;
            funcChanged = true;
        }
    }
    if (funcChanged)
        delta.funcDelta = funcDelta;
    // 3. Diff CWD
    if (base.state.cwd !== current.state.cwd) {
        delta.cwd = current.state.cwd;
    }
    return delta;
}
/**
 * Diffs two VFS snapshots. Handles both raw Maps and MountableFs snapshot objects.
 */
export function diffFs(baseFs, currentFs) {
    const modified = Object.create(null);
    const deleted = [];
    // Cast to internal representation for diffing.
    // FileSystemSnapshot is an opaque branded type; internally it may be a Map
    // (InMemoryFs) or an object with a `base` Map (MountableFs).
    const baseRaw = baseFs;
    const currentRaw = currentFs;
    // Unwrap MountableFs snapshots if necessary
    const bMap = baseRaw && baseRaw.base instanceof Map ? baseRaw.base : baseRaw;
    const cMap = currentRaw && currentRaw.base instanceof Map ? currentRaw.base : currentRaw;
    if (cMap instanceof Map && bMap instanceof Map) {
        for (const [path, entry] of cMap.entries()) {
            const baseEntry = bMap.get(path);
            if (!baseEntry) {
                // New entry
                if (entry.type === "file" && "content" in entry) {
                    modified[path] = entry.content;
                }
            }
            else if (entry.type === "file" && "content" in entry) {
                // Check for content change
                if (entry.content !== baseEntry.content) {
                    modified[path] = entry.content;
                }
            }
        }
        for (const path of bMap.keys()) {
            if (!cMap.has(path)) {
                deleted.push(path);
            }
        }
    }
    return { modified, deleted };
}
/**
 * Applies a delta to an interpreter state.
 */
export function applyStateDelta(state, delta) {
    // 1. Apply Env
    if (delta.envDelta) {
        for (const [key, val] of Object.entries(delta.envDelta)) {
            if (val === null) {
                state.env.delete(key);
            }
            else {
                state.env.set(key, val);
            }
        }
    }
    // 2. Apply Functions
    if (delta.funcDelta) {
        for (const [name, body] of Object.entries(delta.funcDelta)) {
            if (body === null) {
                state.functions.delete(name);
            }
            else {
                // Placeholder
            }
        }
    }
    // 3. Apply CWD
    if (delta.cwd) {
        state.cwd = delta.cwd;
    }
}
