import { readFile } from "node:fs/promises";
import { homedir } from "node:os";
import { join } from "node:path";
import { registerBuiltInGatewayPlatforms } from "./adapters.js";
import { defaultGatewayPlatformRegistry } from "./platform-registry.js";
function chatConfigPath(agentDir) {
    return join(agentDir, "chat", "config.json");
}
async function loadGatewayDeliveryConfig(agentDir) {
    try {
        return JSON.parse(await readFile(chatConfigPath(agentDir), "utf-8"));
    }
    catch {
        const fallbackPath = join(homedir(), ".pie", "agent", "chat", "config.json");
        if (fallbackPath === chatConfigPath(agentDir))
            return { accounts: {} };
        try {
            return JSON.parse(await readFile(fallbackPath, "utf-8"));
        }
        catch {
            return { accounts: {} };
        }
    }
}
function listDestinations(config) {
    const destinations = [];
    for (const [accountId, account] of Object.entries(config.accounts ?? {})) {
        if (account.service === "discord") {
            const discord = account;
            if (discord.homeChannelId) {
                destinations.push({
                    service: account.service,
                    accountId,
                    channelKey: "home",
                    channelId: discord.homeChannelId,
                    label: `${accountId}/home`,
                });
            }
        }
        for (const [channelKey, channel] of Object.entries(account.channels ?? {})) {
            destinations.push({
                service: account.service,
                accountId,
                channelKey,
                channelId: channel.id,
                label: `${accountId}/${channelKey}`,
            });
        }
    }
    return destinations;
}
export function parseGatewayDeliverTargets(deliver) {
    const value = deliver?.trim() || "local";
    if (value === "local")
        return ["local"];
    return value
        .split(",")
        .map((part) => part.trim())
        .filter(Boolean);
}
function resolveDestinations(config, deliver, origin, registry = defaultGatewayPlatformRegistry) {
    const all = listDestinations(config);
    const destinations = new Map();
    const errors = [];
    const add = (destination, ref) => {
        if (!destination) {
            errors.push(`no delivery target resolved for ${ref}`);
            return;
        }
        destinations.set(destination.label, destination);
    };
    for (const part of parseGatewayDeliverTargets(deliver)) {
        if (part === "local")
            continue;
        if (part === "origin") {
            add(origin ? all.find((candidate) => candidate.label === origin) : undefined, "origin");
            continue;
        }
        if (part === "all") {
            for (const destination of all)
                add(destination, "all");
            continue;
        }
        if (part.startsWith("chat:")) {
            const conversationId = part.slice("chat:".length).replace(/^\/+/, "").replace(/\/+$/, "");
            add(all.find((candidate) => candidate.label === conversationId), part);
            continue;
        }
        const separator = part.indexOf(":");
        if (separator > 0) {
            const service = part.slice(0, separator);
            const rawChannelId = part.slice(separator + 1);
            const platform = registry.has(service);
            if (platform) {
                add(all.find((candidate) => candidate.service === service && candidate.channelId === rawChannelId), part);
                continue;
            }
        }
        add(all.find((candidate) => candidate.label === part), part);
    }
    return { destinations: [...destinations.values()], errors };
}
export async function deliverGatewayMessage(options) {
    const parts = parseGatewayDeliverTargets(options.deliver);
    if (parts.length === 0 || (parts.length === 1 && parts[0] === "local")) {
        return { delivered: 0, errors: [], targets: [] };
    }
    const registry = registerBuiltInGatewayPlatforms(options.registry ?? defaultGatewayPlatformRegistry);
    const config = await loadGatewayDeliveryConfig(options.agentDir);
    const { destinations, errors } = resolveDestinations(config, options.deliver, options.origin, registry);
    let delivered = 0;
    for (const destination of destinations) {
        try {
            const account = config.accounts?.[destination.accountId];
            if (!account)
                throw new Error(`account not found: ${destination.accountId}`);
            const platform = registry.require(destination.service);
            if (!platform.sendMessage)
                throw new Error(`gateway platform cannot send standalone messages: ${destination.service}`);
            const supportsAttachments = platform.capabilities?.attachments === true;
            const attachmentPaths = options.attachmentPaths?.length && supportsAttachments ? options.attachmentPaths : undefined;
            const content = options.attachmentPaths?.length && !supportsAttachments
                ? [options.content, ...options.attachmentPaths.map((path) => `[attachment: ${path}]`)].join("\n")
                : options.content;
            await platform.sendMessage(account, destination.channelId, content, attachmentPaths ? { attachmentPaths } : undefined);
            delivered++;
        }
        catch (error) {
            errors.push(`${destination.label}: ${error instanceof Error ? error.message : String(error)}`);
        }
    }
    return { delivered, errors, targets: destinations.map((destination) => destination.label) };
}
//# sourceMappingURL=delivery.js.map