import { describe, expect, it, vi } from 'vitest';
import { DefaultPathBuilder } from '../../../session/workspace/path-builder.js';
import { RunContextFactory } from '../context.js';
function mockProvider() {
    return {
        id: 'mock',
        supports: () => true,
        chat: async () => ({ message: { role: 'assistant', content: '' } }),
    };
}
function buildConfig(overrides = {}) {
    const sessionId = 'ses_test';
    const threadId = 'thd_test';
    const projectId = 'prj_test';
    const tenantId = 'tnt_test';
    const runConfig = {
        model: 'test',
        tokenBudget: 1_000,
        timeoutMs: 5_000,
    };
    return {
        agentId: 'agent-1',
        agentName: 'agent-1',
        runConfig,
        provider: mockProvider(),
        messages: [],
        sessionId,
        threadId,
        projectId,
        tenantId,
        workingDirectory: '/tmp/run-context-test',
        ...overrides,
    };
}
describe('RunContextFactory.build', () => {
    it('requires sessionId, threadId, projectId, tenantId and returns them on the context', () => {
        const cfg = buildConfig();
        const ctx = RunContextFactory.build(cfg);
        expect(ctx.sessionId).toBe(cfg.sessionId);
        expect(ctx.threadId).toBe(cfg.threadId);
        expect(ctx.projectId).toBe(cfg.projectId);
        expect(ctx.tenantId).toBe(cfg.tenantId);
    });
    it('uses the injected PathBuilder to resolve the output dir (no hardcoded .namzu/threads)', () => {
        const pathBuilderMock = {
            rootDir: vi.fn(() => '/mock/root'),
            projectDir: vi.fn((pid) => `/mock/root/projects/${pid}`),
            sessionDir: vi.fn((pid, sid) => `/mock/root/projects/${pid}/sessions/${sid}`),
            subSessionDir: vi.fn(),
            runDir: vi.fn(),
        };
        const cfg = buildConfig({ pathBuilder: pathBuilderMock });
        const ctx = RunContextFactory.build(cfg);
        expect(pathBuilderMock.sessionDir).toHaveBeenCalledWith(cfg.projectId, cfg.sessionId);
        expect(ctx.outputDir).toBe(`/mock/root/projects/${cfg.projectId}/sessions/${cfg.sessionId}`);
        // Legacy hardcoded path must not leak.
        expect(ctx.outputDir).not.toContain('.namzu/threads');
    });
    it('falls back to DefaultPathBuilder rooted at {cwd}/.namzu when no pathBuilder is provided', () => {
        const cfg = buildConfig();
        const ctx = RunContextFactory.build(cfg);
        // Layout lives under projects/{pid}/sessions/{sid} — no `.namzu/threads/`.
        expect(ctx.outputDir).toContain('/.namzu/projects/prj_test/sessions/ses_test');
        expect(ctx.outputDir).not.toContain('threads');
    });
    it('seeds RunPersistence with propagated sessionId/threadId/tenantId/projectId', () => {
        const cfg = buildConfig();
        const ctx = RunContextFactory.build(cfg);
        expect(ctx.runMgr.sessionId).toBe(cfg.sessionId);
        expect(ctx.runMgr.threadId).toBe(cfg.threadId);
        expect(ctx.runMgr.tenantId).toBe(cfg.tenantId);
        expect(ctx.runMgr.projectId).toBe(cfg.projectId);
    });
    it('reuses the runId supplied by the caller', () => {
        const runId = 'run_fixed';
        const ctx = RunContextFactory.build(buildConfig({ runId }));
        expect(ctx.runId).toBe(runId);
    });
    it('DefaultPathBuilder lays out runs under sessions/{sessionId}/runs', () => {
        const builder = new DefaultPathBuilder('/base/.namzu');
        const runDir = builder.runDir('prj_x', 'ses_y', 'run_z');
        expect(runDir).toBe('/base/.namzu/projects/prj_x/sessions/ses_y/runs/run_z');
    });
});
//# sourceMappingURL=context.test.js.map