/**
 * Regression-protection for the engine-bootstrap wiring (mmnto-ai/totem#1794).
 *
 * `lint.test.ts` covers the lint wiring. This file mirrors that assertion
 * for the other three command surfaces added in this PR — `shield`,
 * `compile`, and `test-rules` — so a future edit that drops the
 * `bootstrapEngine(config, configRoot)` call from any one of them fails
 * loud instead of silently regressing pack consumption end-to-end.
 *
 * Each test invokes the command and tolerates a downstream failure
 * (no diff, no lessons, no rules file) — the spy captures the
 * bootstrap call before the command can fail, which is the only
 * assertion we need.
 */
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { cleanTmpDir } from '../test-utils.js';
const bootstrapEngineMock = vi.fn();
vi.mock('../utils/bootstrap-engine.js', () => ({
    bootstrapEngine: (config, projectRoot) => bootstrapEngineMock(config, projectRoot),
}));
vi.mock('../utils.js', async () => {
    const actual = await vi.importActual('../utils.js');
    return {
        ...actual,
        resolveConfigPath: (cwd) => path.join(cwd, 'totem.config.ts'),
        loadConfig: async () => ({
            targets: [],
            totemDir: '.totem',
            ignorePatterns: [],
        }),
        loadEnv: () => { },
    };
});
function makeTmpDir() {
    return fs.mkdtempSync(path.join(os.tmpdir(), 'totem-bootstrap-wiring-'));
}
function expectBootstrapCalledOnceWithConfigAndRoot(expectedRoot) {
    expect(bootstrapEngineMock).toHaveBeenCalledTimes(1);
    const [calledConfig, calledRoot] = bootstrapEngineMock.mock.calls[0];
    expect(calledConfig).toMatchObject({ totemDir: '.totem' });
    expect(typeof calledRoot).toBe('string');
    // macOS resolves `os.tmpdir()` `/tmp/...` → `/private/tmp/...` after
    // `process.chdir`, but the fixture string stays `/tmp/...`. Canonicalize
    // both sides via `fs.realpathSync.native` so the assertion compares
    // logical identity, not raw string equality. `.native` (vs the JS-only
    // variant) also expands Windows 8.3 short names, so the comparison is
    // robust on every CI runner.
    expect(fs.realpathSync.native(calledRoot)).toBe(fs.realpathSync.native(expectedRoot));
}
/**
 * Tolerate the downstream throw on a `bootstrapEngine` wiring test —
 * the command will fail later (no diff, no lessons, no rules file)
 * but the spy captures the bootstrap call first, which is the only
 * thing this test cares about. Asserting the rejection is an `Error`
 * keeps the catch non-empty per the project's "no empty catches" rule
 * and prevents a regression where the command resolves cleanly without
 * ever triggering the downstream code path that exercises bootstrap.
 */
function tolerateDownstreamThrow(p) {
    return p.then(() => {
        // If the command resolves cleanly, the bootstrap-spy assertion
        // below still runs — but this catch-arm exists to keep the
        // negative case visible. A future change that makes the command
        // resolve without invoking bootstrap would still fail the
        // toHaveBeenCalledTimes(1) assertion.
    }, (err) => {
        expect(err).toBeInstanceOf(Error);
    });
}
describe('engine bootstrap wiring (mmnto-ai/totem#1794) — non-lint command surfaces', () => {
    let tmpDir;
    let originalCwd;
    beforeEach(() => {
        tmpDir = makeTmpDir();
        originalCwd = process.cwd();
        process.chdir(tmpDir);
        fs.writeFileSync(path.join(tmpDir, 'totem.config.ts'), 'export default {};', 'utf-8');
        bootstrapEngineMock.mockClear();
    });
    afterEach(() => {
        process.chdir(originalCwd);
        cleanTmpDir(tmpDir);
    });
    it('shield (--estimate path) invokes bootstrapEngine with config + configRoot', async () => {
        const { shieldCommand } = await import('./shield.js');
        await tolerateDownstreamThrow(shieldCommand({ estimate: true }));
        expectBootstrapCalledOnceWithConfigAndRoot(tmpDir);
    });
    it('shield (main LLM path) invokes bootstrapEngine with config + configRoot', async () => {
        // shield.ts has TWO wiring sites — the --estimate branch (covered
        // above) and the main LLM-review branch at ~line 1151. A regression
        // that drops the wiring from one path would silently slip past a
        // test that only exercises the other.
        const { shieldCommand } = await import('./shield.js');
        await tolerateDownstreamThrow(shieldCommand({}));
        expectBootstrapCalledOnceWithConfigAndRoot(tmpDir);
    });
    it('compile invokes bootstrapEngine with config + configRoot', async () => {
        const { compileCommand } = await import('./compile.js');
        await tolerateDownstreamThrow(compileCommand({}));
        expectBootstrapCalledOnceWithConfigAndRoot(tmpDir);
    });
    it('test-rules invokes bootstrapEngine with config + configRoot', async () => {
        const { testRulesCommand } = await import('./test-rules.js');
        await tolerateDownstreamThrow(testRulesCommand({}));
        expectBootstrapCalledOnceWithConfigAndRoot(tmpDir);
    });
});
//# sourceMappingURL=bootstrap-wiring.test.js.map