/**
 * Paths that resolve to the process's own stdin. `botmux send` reads stdin for
 * the message body (the documented `echo "msg" | botmux send` form), so passing
 * one of these to `--file`/`--image` makes a single stdin serve two consumers:
 * the body is read first, then the attachment read sees EOF. The attachment
 * upload then fails *after* the primary message was already delivered, so the
 * command exits non-zero for an already-sent message and the caller resends —
 * producing duplicate messages. Reject these up front instead.
 */
const STDIN_ALIAS_PATHS = new Set(['-', '/dev/stdin', '/dev/fd/0', '/proc/self/fd/0']);
/** First attachment path that aliases stdin, or null if none do. */
export function findStdinAliasAttachment(paths) {
    for (const p of paths) {
        if (STDIN_ALIAS_PATHS.has(p.trim()))
            return p;
    }
    return null;
}
/**
 * Upload + post each file as its own message, best-effort. By the time this
 * runs the primary message has already been delivered, so a failure on one
 * attachment must NOT throw: letting it bubble would make the caller report
 * total failure (exit 1) for an already-sent message, which drives resends and
 * duplicates. Collect failures so the caller can surface them as a warning
 * while still reporting the primary send as the success it was.
 */
export async function sendFileAttachments(deps, appId, files) {
    const sent = [];
    const failed = [];
    for (const fp of files) {
        try {
            const fileKey = await deps.uploadFile(appId, fp);
            sent.push(await deps.dispatch(JSON.stringify({ file_key: fileKey }), 'file'));
        }
        catch (err) {
            failed.push({ path: fp, error: err?.message ?? String(err) });
        }
    }
    return { sent, failed };
}
export async function dispatchPrimaryMessage(deps, opts) {
    if (!opts.quoteTargetId) {
        return {
            messageId: await opts.dispatch(opts.content, opts.msgType),
            primaryQuotedId: null,
        };
    }
    try {
        const messageId = await deps.replyMessage(opts.appId, opts.quoteTargetId, opts.content, opts.msgType, false, undefined, opts.hookContext);
        return { messageId, primaryQuotedId: opts.quoteTargetId };
    }
    catch (err) {
        if (err instanceof opts.MessageWithdrawnError) {
            opts.onQuoteWithdrawn?.(opts.quoteTargetId);
            return {
                messageId: await deps.sendMessage(opts.appId, opts.targetChatId, opts.content, opts.msgType, undefined, opts.hookContext),
                primaryQuotedId: null,
            };
        }
        throw err;
    }
}
//# sourceMappingURL=send-dispatch.js.map