import { mkdtemp, mkdir, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { listPermanentMemoriesFromWorkspace, resolvePermanentMemoryStorePath, resolvePermanentMemoryStorePathCandidates, } from "./memory.js";
describe("runtime permanent memory route helpers", () => {
    it("resolves permanent memory under the agent workspace", () => {
        expect(resolvePermanentMemoryStorePath("/workspace/project", "Backend/Engineer:Lead").replace(/\\/g, "/")).toBe("/workspace/project/.agentswork/memory/memory/Backend_Engineer_Lead");
    });
    it("uses a stable fallback directory when role name is blank", () => {
        expect(resolvePermanentMemoryStorePath("/workspace/project", "  ").replace(/\\/g, "/")).toBe("/workspace/project/.agentswork/memory/memory/default-role");
    });
    it("resolves the role directory before the default-role fallback", () => {
        const candidates = resolvePermanentMemoryStorePathCandidates("/workspace/project", "Backend Engineer").map((candidate) => ({
            ...candidate,
            path: candidate.path.replace(/\\/g, "/"),
        }));
        expect(candidates).toEqual([
            {
                path: "/workspace/project/.agentswork/memory/memory/Backend Engineer",
                isFallback: false,
            },
            {
                path: "/workspace/project/.agentswork/memory/memory/default-role",
                isFallback: true,
            },
        ]);
    });
    it("does not duplicate the default-role candidate when role name is blank", () => {
        const candidates = resolvePermanentMemoryStorePathCandidates("/workspace/project", "  ").map((candidate) => ({
            ...candidate,
            path: candidate.path.replace(/\\/g, "/"),
        }));
        expect(candidates).toEqual([
            {
                path: "/workspace/project/.agentswork/memory/memory/default-role",
                isFallback: false,
            },
        ]);
    });
    it("lists only permanent memory records from workspace-local domain files", async () => {
        const workspacePath = await mkdtemp(path.join(os.tmpdir(), "aws-memory-workspace-"));
        const storePath = resolvePermanentMemoryStorePath(workspacePath, "Backend Engineer");
        await mkdir(storePath, { recursive: true });
        await writeFile(path.join(storePath, "core.json"), JSON.stringify({
            by_uri: {
                "core://agent/profile": {
                    id: "m-1",
                    uri: "Core://agent/profile/",
                    content: "profile",
                    memory_type: "memory",
                    createdAt: "2026-01-01T00:00:00.000Z",
                    updatedAt: "2026-01-02T00:00:00.000Z",
                    version: 2,
                },
                "core://task/current": {
                    id: "t-1",
                    uri: "core://task/current",
                    content: "task",
                    memory_type: "task_list",
                    createdAt: "2026-01-01T00:00:00.000Z",
                    updatedAt: "2026-01-03T00:00:00.000Z",
                    version: 1,
                },
            },
        }), "utf-8");
        const records = await listPermanentMemoriesFromWorkspace(workspacePath, "Backend Engineer");
        expect(records).toHaveLength(1);
        expect(records[0]).toMatchObject({
            id: "m-1",
            uri: "core://agent/profile",
            domain: "core",
            path: "agent/profile",
            content: "profile",
            memory_type: "memory",
            version: 2,
        });
    });
    it("falls back to default-role records when the requested role directory is empty", async () => {
        const workspacePath = await mkdtemp(path.join(os.tmpdir(), "aws-memory-workspace-"));
        const fallbackStorePath = resolvePermanentMemoryStorePath(workspacePath, "");
        await mkdir(fallbackStorePath, { recursive: true });
        await writeFile(path.join(fallbackStorePath, "task.json"), JSON.stringify({
            by_uri: {
                "task://todo/current": {
                    id: "m-default-role",
                    uri: "task://todo/current",
                    content: "default role memory should still display",
                    memory_type: "memory",
                    createdAt: "2026-01-01T00:00:00.000Z",
                    updatedAt: "2026-01-02T00:00:00.000Z",
                    version: 1,
                },
            },
        }), "utf-8");
        const records = await listPermanentMemoriesFromWorkspace(workspacePath, "W网盘开发员-2号");
        expect(records).toHaveLength(1);
        expect(records[0]).toMatchObject({
            id: "m-default-role",
            uri: "task://todo/current",
            domain: "task",
            content: "default role memory should still display",
        });
    });
    it("falls back when the requested role directory has no normalized permanent records", async () => {
        const workspacePath = await mkdtemp(path.join(os.tmpdir(), "aws-memory-workspace-"));
        const roleStorePath = resolvePermanentMemoryStorePath(workspacePath, "Backend Engineer");
        const fallbackStorePath = resolvePermanentMemoryStorePath(workspacePath, "");
        await mkdir(roleStorePath, { recursive: true });
        await mkdir(fallbackStorePath, { recursive: true });
        await writeFile(path.join(roleStorePath, "task.json"), JSON.stringify({
            by_uri: {
                "task://todo/server-managed": {
                    id: "task-list-record",
                    uri: "task://todo/server-managed",
                    content: "not a permanent memory",
                    memory_type: "task_list",
                    updatedAt: "2026-01-03T00:00:00.000Z",
                },
            },
        }), "utf-8");
        await writeFile(path.join(fallbackStorePath, "task.json"), JSON.stringify({
            by_uri: {
                "task://todo/permanent": {
                    id: "m-fallback-permanent",
                    uri: "task://todo/permanent",
                    content: "fallback permanent memory",
                    memory_type: "memory",
                    updatedAt: "2026-01-02T00:00:00.000Z",
                },
            },
        }), "utf-8");
        const records = await listPermanentMemoriesFromWorkspace(workspacePath, "Backend Engineer");
        expect(records).toHaveLength(1);
        expect(records[0]).toMatchObject({
            id: "m-fallback-permanent",
            uri: "task://todo/permanent",
            content: "fallback permanent memory",
        });
    });
    it("keeps role-specific permanent memory isolated when the role directory has records", async () => {
        const workspacePath = await mkdtemp(path.join(os.tmpdir(), "aws-memory-workspace-"));
        const roleStorePath = resolvePermanentMemoryStorePath(workspacePath, "Backend Engineer");
        const fallbackStorePath = resolvePermanentMemoryStorePath(workspacePath, "");
        await mkdir(roleStorePath, { recursive: true });
        await mkdir(fallbackStorePath, { recursive: true });
        await writeFile(path.join(roleStorePath, "core.json"), JSON.stringify({
            by_uri: {
                "core://role/specific": {
                    id: "m-role",
                    uri: "core://role/specific",
                    content: "role-specific memory wins",
                    memory_type: "memory",
                    updatedAt: "2026-01-03T00:00:00.000Z",
                },
            },
        }), "utf-8");
        await writeFile(path.join(fallbackStorePath, "core.json"), JSON.stringify({
            by_uri: {
                "core://default/old": {
                    id: "m-default",
                    uri: "core://default/old",
                    content: "old default-role memory",
                    memory_type: "memory",
                    updatedAt: "2026-01-02T00:00:00.000Z",
                },
            },
        }), "utf-8");
        const records = await listPermanentMemoriesFromWorkspace(workspacePath, "Backend Engineer");
        expect(records).toHaveLength(1);
        expect(records[0]).toMatchObject({
            id: "m-role",
            uri: "core://role/specific",
            content: "role-specific memory wins",
        });
    });
});
