import fs from 'node:fs';
import path from 'node:path';
import { execFileSync } from 'node:child_process';
const STATE_KEY = 'session-build-context';
export const DEFAULT_BUILD_CONTEXT_MAX_AGE_MS = 6 * 60 * 60 * 1000;
export function isEligibleBuildContextCwd(spawnCwd, currentCwd) {
    if (!spawnCwd || !currentCwd)
        return false;
    const spawn = path.resolve(spawnCwd);
    const current = path.resolve(currentCwd);
    if (spawn === current)
        return false;
    return current.split(path.sep).includes('.worktrees');
}
export function formatBuildContextRestoreNote(entry) {
    const branchLine = entry.branch ? `  branch:   ${entry.branch}\n` : '';
    return [
        '[BUILD-CONTEXT RESTORE] Before this restart you were building in:',
        `  worktree: ${entry.currentCwd}`,
        branchLine ? branchLine.trimEnd() : null,
        `Your shell is back in ${entry.spawnCwd} after the restart — cd ${entry.currentCwd} before continuing your build.`,
        'Do NOT start over in agent-home; your work is in that worktree.',
    ].filter((line) => line != null).join('\n');
}
export class SessionBuildContextStore {
    state;
    opts;
    constructor(state, opts = {}) {
        this.state = state;
        this.opts = opts;
    }
    record(tmuxSession, spawnCwd, currentCwd) {
        const now = this.now();
        const all = this.readAll();
        const prior = all[tmuxSession];
        const normalizedSpawn = path.resolve(spawnCwd);
        const normalizedCurrent = path.resolve(currentCwd);
        if (prior?.spawnCwd === normalizedSpawn && prior.currentCwd === normalizedCurrent) {
            return;
        }
        const branch = this.readBranch(normalizedCurrent);
        all[tmuxSession] = {
            spawnCwd: normalizedSpawn,
            currentCwd: normalizedCurrent,
            ...(branch ? { branch } : {}),
            updatedAt: now,
        };
        this.writeAll(all);
    }
    getRestore(tmuxSession) {
        const entry = this.readAll()[tmuxSession];
        if (!entry)
            return null;
        if (!isEligibleBuildContextCwd(entry.spawnCwd, entry.currentCwd))
            return null;
        if (this.now() - entry.updatedAt > this.maxAgeMs())
            return null;
        if (!fs.existsSync(entry.currentCwd))
            return null;
        return { entry, note: formatBuildContextRestoreNote(entry) };
    }
    readAll() {
        const raw = this.state.get(STATE_KEY);
        if (!raw || typeof raw !== 'object' || Array.isArray(raw))
            return {};
        const out = {};
        for (const [key, value] of Object.entries(raw)) {
            if (!value || typeof value !== 'object' || Array.isArray(value))
                continue;
            const entry = value;
            if (typeof entry.spawnCwd !== 'string'
                || typeof entry.currentCwd !== 'string'
                || typeof entry.updatedAt !== 'number')
                continue;
            out[key] = {
                spawnCwd: entry.spawnCwd,
                currentCwd: entry.currentCwd,
                ...(typeof entry.branch === 'string' && entry.branch.trim() ? { branch: entry.branch } : {}),
                updatedAt: entry.updatedAt,
            };
        }
        return out;
    }
    writeAll(state) {
        this.state.set(STATE_KEY, state);
    }
    readBranch(cwd) {
        if (!fs.existsSync(cwd))
            return null;
        try {
            const out = (this.opts.execFileSync ?? execFileSync)('git', ['-C', cwd, 'branch', '--show-current'], { encoding: 'utf-8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'] });
            const branch = String(out).trim();
            return branch || null;
        }
        catch {
            // @silent-fallback-ok — branch name is best-effort enrichment; cwd restore still works without it.
            return null;
        }
    }
    now() {
        return this.opts.now?.() ?? Date.now();
    }
    maxAgeMs() {
        return this.opts.maxAgeMs ?? DEFAULT_BUILD_CONTEXT_MAX_AGE_MS;
    }
}
//# sourceMappingURL=SessionBuildContextStore.js.map