import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { useFakeHome } from "../test-support/fake-home.js";
vi.mock("@kenkaiiii/gg-agent", async () => {
    const actual = await vi.importActual("@kenkaiiii/gg-agent");
    return { ...actual, agentLoop: vi.fn(() => (async function* emptyLoop() { })()) };
});
vi.mock("./mcp/index.js", async () => {
    const actual = await vi.importActual("./mcp/index.js");
    return {
        ...actual,
        MCPClientManager: vi.fn(function MCPClientManagerMock() {
            return { connectAll: vi.fn(async () => []), dispose: vi.fn(async () => { }) };
        }),
    };
});
let restoreHome;
let tempHome;
let tempProject;
let sibling;
beforeEach(async () => {
    tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "add-dir-home-"));
    tempProject = await fs.mkdtemp(path.join(os.tmpdir(), "add-dir-project-"));
    sibling = await fs.mkdtemp(path.join(os.tmpdir(), "add-dir-sibling-"));
    restoreHome = useFakeHome(tempHome);
    await fs.mkdir(path.join(tempHome, ".gg"), { recursive: true });
    await fs.writeFile(path.join(tempHome, ".gg", "auth.json"), JSON.stringify({
        anthropic: {
            accessToken: "test-access",
            refreshToken: "test-refresh",
            expiresAt: Date.now() + 3_600_000,
        },
    }));
});
afterEach(async () => {
    restoreHome?.();
    await Promise.all([
        fs.rm(tempHome, { recursive: true, force: true }),
        fs.rm(tempProject, { recursive: true, force: true }),
        fs.rm(sibling, { recursive: true, force: true }),
    ]);
    vi.clearAllMocks();
});
async function createSession() {
    const { AgentSession } = await import("./agent-session.js");
    const session = new AgentSession({
        provider: "anthropic",
        model: "claude-test",
        cwd: tempProject,
        transient: true,
        projectCustomization: false,
        loadExtensions: false,
        orchestrationPrompt: false,
        selfCorrectionHooks: false,
    });
    await session.initialize();
    return session;
}
describe("AgentSession.addDirectory", () => {
    it("adds a root and names it in the rebuilt system prompt", async () => {
        const session = await createSession();
        try {
            expect(session.getAdditionalRoots()).toEqual([]);
            const result = await session.addDirectory(sibling);
            expect(result).toEqual({ ok: true, root: path.resolve(sibling) });
            expect(session.getAdditionalRoots()).toEqual([path.resolve(sibling)]);
            const systemPrompt = String(session.getMessages()[0]?.content ?? "");
            expect(systemPrompt).toContain("Additional roots:");
            expect(systemPrompt).toContain(session.getAdditionalRoots()[0]);
        }
        finally {
            await session.dispose();
        }
    }, 20_000);
    it("removes an added root and rejects roots that were never added", async () => {
        const session = await createSession();
        try {
            expect(await session.removeDirectory(sibling)).toMatchObject({ ok: false });
            expect(await session.addDirectory(sibling)).toMatchObject({ ok: true });
            expect(await session.removeDirectory(sibling)).toEqual({
                ok: true,
                root: path.resolve(sibling),
            });
            expect(session.getAdditionalRoots()).toEqual([]);
            expect(String(session.getMessages()[0]?.content ?? "")).not.toContain("Additional roots:");
        }
        finally {
            await session.dispose();
        }
    }, 20_000);
    it("rejects a file, a missing path, and a duplicate", async () => {
        const session = await createSession();
        try {
            const file = path.join(sibling, "a.txt");
            await fs.writeFile(file, "x");
            expect(await session.addDirectory(file)).toMatchObject({ ok: false });
            expect(await session.addDirectory(path.join(sibling, "nope"))).toMatchObject({ ok: false });
            expect(await session.addDirectory(tempProject)).toMatchObject({ ok: false });
            expect(await session.addDirectory(sibling)).toMatchObject({ ok: true });
            expect(await session.addDirectory(sibling)).toMatchObject({ ok: false });
            expect(session.getAdditionalRoots()).toHaveLength(1);
        }
        finally {
            await session.dispose();
        }
    }, 20_000);
});
//# sourceMappingURL=agent-session-add-dir.test.js.map