/**
 * TelegramLiveSender — the real Telegram `SurfaceSender` for the live-test harness
 * (docs/specs/live-user-channel-proof-standard.md §5.4). It posts a message into a
 * Telegram forum topic AS A NON-AGENT IDENTITY (a DEMO bot / second account in a demo
 * group — NOT the agent's own bot, which the agent would not treat as inbound), then
 * waits for the AGENT's reply by polling the topic history for the next agent-authored
 * message.
 *
 * Same shape as SlackLiveSender: the send transport (the demo-bot post) and the
 * history read are INJECTED, so the CODE is complete + unit-testable here and the only
 * wiring-time dependency is the demo-bot CREDENTIAL + a demo group/topic (provisioning).
 *
 * The agent's reply is identified DETERMINISTICALLY: the earliest history entry with
 * `fromUser === false` (an agent outbound) whose messageId is strictly after the one we
 * sent. Null on timeout. The responder-MACHINE attribution (the cross-machine proof) is
 * the RealChannelDriver's injected placement reader, not this sender.
 */
export class TelegramLiveSender {
    d;
    constructor(deps) { this.d = deps; }
    now() { return (this.d.now ?? Date.now)(); }
    async sleep(ms) {
        return (this.d.sleep ?? ((m) => new Promise((r) => setTimeout(r, m))))(ms);
    }
    log(m) { this.d.logger?.(`[telegram-live-sender] ${m}`); }
    topicNum(channelId) {
        const n = Number(channelId);
        if (!Number.isFinite(n))
            throw new Error(`telegram channelId "${channelId}" is not a numeric topic id`);
        return n;
    }
    async send(channelId, text) {
        const res = await this.d.postAsDemoUser(this.topicNum(channelId), text);
        if (!Number.isFinite(res?.messageId)) {
            throw new Error(`postAsDemoUser returned no messageId — message not posted`);
        }
        return { messageId: String(res.messageId) };
    }
    async awaitReply(channelId, opts) {
        const topic = this.topicNum(channelId);
        const afterId = opts.afterMessageId != null ? Number(opts.afterMessageId) : -Infinity;
        const deadline = this.now() + opts.timeoutMs;
        const pollMs = this.d.pollIntervalMs ?? 2000;
        for (let first = true; first || this.now() < deadline; first = false) {
            const reply = await this.findAgentReply(topic, afterId);
            if (reply)
                return reply;
            if (this.now() >= deadline)
                break;
            await this.sleep(pollMs);
        }
        this.log(`no agent reply in topic ${topic} within ${opts.timeoutMs}ms`);
        return null;
    }
    async findAgentReply(topicId, afterId) {
        const entries = await this.d.getHistory(topicId, 100);
        // Oldest-first by messageId so we return the EARLIEST agent reply after the prompt.
        const oldestFirst = [...entries].sort((a, b) => a.messageId - b.messageId);
        for (const e of oldestFirst) {
            if (e.messageId <= afterId)
                continue; // strictly after the prompt
            if (e.fromUser)
                continue; // skip inbound user messages (incl. our own demo post)
            return { text: e.text ?? '', messageId: String(e.messageId) };
        }
        return null;
    }
}
//# sourceMappingURL=TelegramLiveSender.js.map