import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { getAgentDir } from "../../../config.js";
export const CHAT_HOME = join(getAgentDir(), "chat");
export const CHAT_CONFIG_PATH = join(CHAT_HOME, "config.json");
export const CHAT_CACHE_DIR = join(CHAT_HOME, "cache");
function sanitizePathSegment(value) {
    return value.replace(/[^a-zA-Z0-9._-]+/g, "_");
}
function getAccountStorageDir(accountId) {
    return join(CHAT_HOME, "accounts", sanitizePathSegment(accountId));
}
function getChannelStorageDir(accountId, channelKey) {
    return join(getAccountStorageDir(accountId), "channels", sanitizePathSegment(channelKey));
}
function mergeAccess(...policies) {
    const merged = {};
    for (const policy of policies) {
        if (!policy)
            continue;
        if (policy.trigger !== undefined)
            merged.trigger = policy.trigger;
        if (policy.ignoreBots !== undefined)
            merged.ignoreBots = policy.ignoreBots;
        if (policy.allowedUserIds !== undefined)
            merged.allowedUserIds = [...policy.allowedUserIds];
        if (policy.allowedRoleIds !== undefined)
            merged.allowedRoleIds = [...policy.allowedRoleIds];
    }
    return merged;
}
function mergeGondolinSecrets(...configs) {
    const merged = {};
    for (const config of configs) {
        for (const [name, secret] of Object.entries(config?.secrets ?? {})) {
            merged[name] = { value: secret.value, hosts: [...secret.hosts] };
        }
    }
    return merged;
}
export function buildResolvedConversation(config, accountId, channelKey, channel) {
    const account = config.accounts[accountId];
    if (!account)
        throw new Error(`Unknown account: ${accountId}`);
    const accountDir = getAccountStorageDir(accountId);
    const conversationDir = getChannelStorageDir(accountId, channelKey);
    const workspaceDir = join(conversationDir, "workspace");
    return {
        service: account.service,
        botName: config.botName?.trim() || "pie",
        accountId,
        account,
        channelKey,
        channel,
        conversationId: `${accountId}/${channelKey}`,
        conversationName: `${account.name ?? accountId} / ${channel.name ?? channelKey}`,
        access: mergeAccess(account.access, channel.access),
        gondolinSecrets: mergeGondolinSecrets(config.gondolin, account.gondolin, channel.gondolin),
        accountDir,
        sharedDir: join(accountDir, "shared"),
        conversationDir,
        workspaceDir,
        gondolinDir: join(conversationDir, "gondolin"),
        accountMemoryPath: join(accountDir, "shared", "memory.md"),
        channelMemoryPath: join(conversationDir, "workspace", "memory.md"),
        logPath: join(conversationDir, "channel.jsonl"),
        filesDir: join(workspaceDir, "incoming"),
        lockPath: join(conversationDir, ".lock"),
    };
}
export async function ensureChatHome() {
    await mkdir(CHAT_HOME, { recursive: true });
    await mkdir(CHAT_CACHE_DIR, { recursive: true });
}
export async function removeAccountStorage(accountId) {
    await rm(getAccountStorageDir(accountId), { recursive: true, force: true });
    await rm(join(CHAT_CACHE_DIR, `${sanitizePathSegment(accountId)}.json`), { force: true });
}
export async function removeChannelStorage(accountId, channelKey) {
    await rm(getChannelStorageDir(accountId, channelKey), { recursive: true, force: true });
}
export async function saveChatConfig(config) {
    await ensureChatHome();
    await writeFile(CHAT_CONFIG_PATH, `${JSON.stringify(config, null, "\t")}\n`, "utf8");
}
export async function loadChatConfig() {
    await ensureChatHome();
    try {
        const content = await readFile(CHAT_CONFIG_PATH, "utf8");
        const parsed = JSON.parse(content);
        return {
            botName: parsed.botName?.trim() || "pie",
            gondolin: parsed.gondolin,
            accounts: (parsed.accounts ?? {}),
        };
    }
    catch {
        return { botName: "pie", accounts: {} };
    }
}
export function listConfiguredConversations(config) {
    const conversations = [];
    for (const [accountId, account] of Object.entries(config.accounts)) {
        for (const [channelKey, channel] of Object.entries(account.channels ?? {})) {
            conversations.push(buildResolvedConversation(config, accountId, channelKey, channel));
        }
    }
    return conversations.sort((a, b) => a.conversationId.localeCompare(b.conversationId));
}
export function resolveConversation(config, spec) {
    const trimmed = spec.trim().replace(/^\/+/, "").replace(/\/+$/, "");
    if (!trimmed)
        return undefined;
    const parts = trimmed.split("/").filter(Boolean);
    if (parts.length !== 2)
        return undefined;
    const [accountId, channelKey] = parts;
    const account = config.accounts[accountId];
    const channel = account?.channels?.[channelKey];
    if (!account || !channel)
        return undefined;
    return buildResolvedConversation(config, accountId, channelKey, channel);
}
//# sourceMappingURL=config.js.map