import { Router } from "express";
import { promises as fs } from "node:fs";
import path from "node:path";
import { validateToken } from "../middleware/auth.js";
export const memoryRouter = Router();
const URI_PATTERN = /^([a-zA-Z_][a-zA-Z0-9_]*):\/\/(.*)$/;
const PATH_UNSAFE_CHARACTERS = new Set([
    "<",
    ">",
    ":",
    '"',
    "/",
    "\\",
    "|",
    "?",
    "*",
]);
/**
 * 解析角色级记忆目录名。
 * 主流程：清理路径分隔符等非法字符，保证 UI 读取路径与 MCP 写入路径一致。
 */
function resolveRoleMemoryDirectoryName(roleName) {
    const safeRoleName = String(roleName || "")
        .trim()
        .split("")
        .map((character) => PATH_UNSAFE_CHARACTERS.has(character) || character.charCodeAt(0) < 32
        ? "_"
        : character)
        .join("")
        .replace(/^\.+|\.+$/g, "")
        .trim();
    return safeRoleName || "default-role";
}
/**
 * 解析永久记忆目录。
 * 主流程：使用请求中的 Agent 工作区路径和角色名，定位 .agentswork/memory/memory/<roleName> 分域 JSON 文件。
 */
export function resolvePermanentMemoryStorePath(workspacePath, roleName = "") {
    const normalizedWorkspacePath = String(workspacePath || "").trim();
    if (!normalizedWorkspacePath) {
        throw new Error("workspacePath is required");
    }
    return path.join(path.normalize(normalizedWorkspacePath), ".agentswork", "memory", "memory", resolveRoleMemoryDirectoryName(roleName));
}
/**
 * 解析可读取的永久记忆目录候选。
 * 主流程：优先使用 Agent 绑定角色目录；当早期/预设 Agent 未注入 AWS_ROLE_NAME 时，再回退读取 default-role。
 */
export function resolvePermanentMemoryStorePathCandidates(workspacePath, roleName = "") {
    const primaryPath = resolvePermanentMemoryStorePath(workspacePath, roleName);
    const fallbackPath = resolvePermanentMemoryStorePath(workspacePath, "");
    if (primaryPath === fallbackPath) {
        return [{ path: primaryPath, isFallback: false }];
    }
    return [
        { path: primaryPath, isFallback: false },
        { path: fallbackPath, isFallback: true },
    ];
}
function normalizeUri(input) {
    const matched = URI_PATTERN.exec(String(input || "").trim());
    if (!matched) {
        throw new Error(`Invalid memory uri: ${input}`);
    }
    const domain = matched[1]?.toLowerCase();
    const normalizedPath = (matched[2] || "").replace(/^\/+|\/+$/g, "");
    if (!domain || !normalizedPath) {
        throw new Error(`Invalid memory uri: ${input}`);
    }
    return {
        uri: `${domain}://${normalizedPath}`,
        domain,
        path: normalizedPath,
    };
}
function normalizeMemoryRecord(uri, record) {
    const memoryType = record.memory_type || "memory";
    if (memoryType !== "memory") {
        return null;
    }
    const normalized = normalizeUri(record.uri || uri);
    return {
        id: String(record.id || normalized.uri),
        uri: normalized.uri,
        domain: normalized.domain,
        path: normalized.path,
        content: String(record.content || ""),
        memory_type: "memory",
        createdAt: String(record.createdAt || record.updatedAt || ""),
        updatedAt: String(record.updatedAt || record.createdAt || ""),
        version: typeof record.version === "number" ? record.version : 1,
    };
}
/**
 * 读取工作区永久记忆。
 * 主流程：遍历 domain JSON -> 规范化记录 -> 仅返回 memory 类型并按更新时间倒序展示。
 */
async function listPermanentMemoriesFromStorePath(storePath) {
    let entries;
    try {
        entries = await fs.readdir(storePath);
    }
    catch (error) {
        const err = error;
        if (err.code === "ENOENT") {
            return [];
        }
        throw new Error(`memory store is not accessible: ${storePath}${err.message ? ` (${err.message})` : ""}`);
    }
    const records = [];
    for (const entry of entries) {
        if (!entry.endsWith(".json")) {
            continue;
        }
        const filePath = path.join(storePath, entry);
        const raw = await fs.readFile(filePath, "utf-8");
        const parsed = JSON.parse(raw);
        const byUri = parsed.by_uri && typeof parsed.by_uri === "object" ? parsed.by_uri : {};
        for (const [uri, record] of Object.entries(byUri)) {
            const normalized = normalizeMemoryRecord(uri, record);
            if (normalized) {
                records.push(normalized);
            }
        }
    }
    records.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
    return records;
}
/**
 * 读取工作区永久记忆。
 * 主流程：优先读角色目录；若角色目录无内容，兼容读取 default-role 中由未注入 AWS_ROLE_NAME 的 MCP 写入的旧数据。
 */
export async function listPermanentMemoriesFromWorkspace(workspacePath, roleName = "") {
    let fallbackRecords = [];
    for (const candidate of resolvePermanentMemoryStorePathCandidates(workspacePath, roleName)) {
        const records = await listPermanentMemoriesFromStorePath(candidate.path);
        if (!candidate.isFallback || records.length > 0) {
            if (!candidate.isFallback && records.length > 0) {
                return records;
            }
            if (candidate.isFallback) {
                fallbackRecords = records;
            }
        }
    }
    return fallbackRecords;
}
memoryRouter.post("/memory/list", validateToken, async (req, res) => {
    try {
        const workspacePath = String(req.body?.workspacePath || "");
        const roleName = String(req.body?.roleName || "");
        const records = await listPermanentMemoriesFromWorkspace(workspacePath, roleName);
        res.json(records);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        res.status(400).json({ error: message });
    }
});
