/**
 * cmd-fixtures.mjs — shared builders for in-process unit tests.
 *
 * The integration test suite already has makeFixtureProject (TypeScript) and
 * createTmpProject (TypeScript). Those keep their existing surface for
 * subprocess tests. The new in-process Layer 1 tests use these JS-side
 * helpers so they can be imported from `.mjs` test files alongside the
 * cmd functions they exercise.
 */
import { spawnSync } from 'node:child_process';
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
/**
 * Create a throwaway project dir with `.aperant/` initialized, run `fn(dir)`,
 * and clean up on completion (success or throw). Mirrors `createTmpProject`
 * + a `try/finally` rmSync, with a smaller surface — most in-process tests
 * only need the dir path.
 *
 * @param {(dir: string) => unknown | Promise<unknown>} fn
 * @param {{ gitInit?: boolean }} [opts]
 * @returns {Promise<unknown>} fn's return value (await-friendly).
 */
export async function withTempProject(fn, opts = {}) {
    const dir = mkdtempSync(join(tmpdir(), 'apt-cmd-'));
    const gitInit = opts.gitInit !== false;
    if (gitInit) {
        spawnSync('git', ['init', '-q', '-b', 'main'], { cwd: dir });
        spawnSync('git', ['config', 'user.email', 'test@example.com'], { cwd: dir });
        spawnSync('git', ['config', 'user.name', 'test'], { cwd: dir });
        spawnSync('git', ['config', 'commit.gpgsign', 'false'], { cwd: dir });
        writeFileSync(join(dir, 'README.md'), '# test\n');
        spawnSync('git', ['add', 'README.md'], { cwd: dir });
        spawnSync('git', ['commit', '-q', '-m', 'init'], { cwd: dir });
    }
    mkdirSync(join(dir, '.aperant'), { recursive: true });
    mkdirSync(join(dir, '.aperant', 'tasks'), { recursive: true });
    mkdirSync(join(dir, '.aperant', 'events'), { recursive: true });
    mkdirSync(join(dir, '.aperant', 'locks'), { recursive: true });
    mkdirSync(join(dir, '.aperant', 'roadmap'), { recursive: true });
    mkdirSync(join(dir, '.aperant', 'roadmap', 'project'), { recursive: true });
    const now = new Date().toISOString();
    writeFileSync(join(dir, '.aperant', 'state.json'), `${JSON.stringify({
        version: 1,
        initialized_at: now,
        last_activity: now,
        active_tasks: {},
        completed_tasks: [],
        decisions: {},
        has_tests: false,
    }, null, 2)}\n`);
    writeFileSync(join(dir, '.aperant', 'config.json'), `${JSON.stringify({ version: 3, autonomy_level: 2, project_type: 'monorepo' }, null, 2)}\n`);
    writeFileSync(join(dir, '.aperant', 'tasks', 'INDEX.md'), '# Task Index\n\n');
    writeFileSync(join(dir, '.aperant', 'roadmap', 'project', 'milestones.json'), `${JSON.stringify({ version: 1, project: 'test', scope: 'project', milestones: [] }, null, 2)}\n`);
    writeFileSync(join(dir, '.aperant', 'team.json'), `${JSON.stringify({ version: 1, enabled: true, members: {} }, null, 2)}\n`);
    try {
        return await fn(dir);
    }
    finally {
        try {
            rmSync(dir, { recursive: true, force: true });
        }
        catch {
            /* best-effort */
        }
    }
}
/**
 * Seed a task into .aperant/state.json's active_tasks map.
 *
 * @param {string} projectDir
 * @param {{
 *   id: string,
 *   description?: string,
 *   scope?: string,
 *   milestone_id?: string | null,
 *   phase_id?: string | null,
 *   lifecycle_phase?: string,
 * }} opts
 */
export function seedTask(projectDir, opts) {
    const statePath = join(projectDir, '.aperant', 'state.json');
    const state = JSON.parse(readFileSync(statePath, 'utf-8'));
    state.active_tasks[opts.id] = {
        id: opts.id,
        description: opts.description ?? `seeded: ${opts.id}`,
        scope: opts.scope ?? 'project',
        milestone_id: opts.milestone_id ?? null,
        phase_id: opts.phase_id ?? null,
        lifecycle_phase: opts.lifecycle_phase ?? 'executing',
        created_at: new Date().toISOString(),
        history: [],
    };
    writeFileSync(statePath, `${JSON.stringify(state, null, 2)}\n`);
}
/**
 * Toggle the auto_close_phase config flag — many task lifecycle tests
 * exercise the close-phase cascade and need this flipped on.
 *
 * @param {string} projectDir
 */
export function enableAutoClosePhase(projectDir) {
    const cfgPath = join(projectDir, '.aperant', 'config.json');
    const cfg = JSON.parse(readFileSync(cfgPath, 'utf-8'));
    cfg.task_lifecycle = cfg.task_lifecycle ?? {};
    cfg.task_lifecycle.auto_close_phase = true;
    writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}\n`);
}
/** Read state.json from a project dir. */
export function readState(projectDir) {
    return JSON.parse(readFileSync(join(projectDir, '.aperant', 'state.json'), 'utf-8'));
}
//# sourceMappingURL=cmd-fixtures.mjs.map