import { Client as HttpClient } from '@microsoft/teams.common';
/**
 * The Socket Mode protocol version teams.ts speaks. Every reply frame must carry
 * it so Teams backend service can detect a mismatch. Bump only in lockstep
 * with Teams backend service's `SocketProtocol.CurrentVersion`.
 */
export declare const SOCKET_MODE_PROTOCOL_VERSION = 1;
/**
 * The negotiate route appended to the Teams backend service base URL. Teams backend service exposes the Socket Mode
 * handshake at `POST {base}/v3/websockets/connect`.
 */
export declare const SOCKET_MODE_NEGOTIATE_PATH = "/v3/websockets/connect";
/**
 * Lifecycle status of the {@link SocketModeAdapter} socket.
 *
 * - `idle` — created but not yet started.
 * - `connecting` — negotiating and opening the socket, or reconnecting.
 * - `ready` — socket is open AND the Teams backend service `SocketReady` readiness contract has
 *   been satisfied; inbound activities can be delivered.
 * - `disconnected` — the socket closed. A reconnect may be in progress, unless
 *   negotiate was rejected with HTTP 401/403, in which case reconnecting stops
 *   until the app is restarted with corrected credentials or access.
 * - `stopped` — the server was stopped and will not reconnect.
 *
 * @experimental This API is in preview and may change in the future.
 */
export type SocketModeStatus = 'idle' | 'connecting' | 'ready' | 'disconnected' | 'stopped';
/**
 * Options controlling the inbound Socket Mode transport, passed as
 * `new App({ socketMode: { ... } })`. Passing `socketMode: true` uses all
 * defaults.
 * WebSocket is only recommended for use when developing agents.
 * Socket Mode is currently only available for new bots.
 *
 * @experimental This API is in preview and may change in the future.
 */
export type SocketModeOptions = {
    /**
     * Geographies to connect to. One independent socket is opened per geo, with
     * the geo prefixed to the SDK-owned negotiate hostname
     * (`https://{geo}.botapi.skype.com/v3/websockets/connect`), so a single bot has
     * inbound coverage across regions — a conversation pinned to another geo is
     * still delivered over the socket instead of silently falling back to HTTP.
     *
     * Omitted or empty lists default to `['amer', 'emea', 'apac']`. Every listed
     * geo must connect for `App.start()` to succeed; each is then supervised
     * independently, so one geo dropping never affects delivery on the others.
     * Geo values must be non-empty and case-insensitively unique.
     *
     * @default ['amer', 'emea', 'apac']
     */
    readonly geos?: readonly string[];
};
/**
 * Result of a successful Teams backend service negotiate call. Mirrors the Teams backend service response body.
 */
export type NegotiateResult = {
    /** Azure SignalR URL to open the socket against. */
    readonly url: string;
    /** Bearer access token for the Azure SignalR connection. */
    readonly accessToken: string;
    /** Token lifetime in seconds. */
    readonly expiresIn: number;
};
/**
 * The `SocketReady` frame Teams backend service pushes once the connection is registered in the
 * bot's group and inbound delivery can begin.
 */
export type SocketReadyFrame = {
    readonly botKey?: string;
    readonly connectionId?: string;
};
/**
 * The envelope Teams backend service delivers on the SignalR `Activity` client method. Field
 * casing may vary with the hub protocol, so always read via the
 * `readEnvelope*` helpers rather than by direct property access.
 */
export type SocketActivityEnvelope = {
    /** Protocol version Teams backend service used to encode this envelope. */
    readonly protocolVersion?: number;
    /** Correlation id echoed back on the reply frame. */
    readonly envelopeId?: string;
    /** `"invoke"` for invoke activities; the activity type otherwise. */
    readonly type?: string;
    /**
     * Whether Teams backend service expects a delivery acknowledgement. `true` for one-way
     * activities; invoke activities expect a full result instead.
     */
    readonly ackRequired?: boolean;
    /** The Bot Framework activity payload. */
    readonly payload?: unknown;
    /** Optional activity payload alias used by some Teams backend service builds. */
    readonly activity?: unknown;
    /** MS-CV correlation vector for log stitching. */
    readonly cv?: string;
    /**
     * Bot key the backend service addressed this delivery to. Informational only:
     * reply frames always carry the locally configured bot's client id instead.
     */
    readonly botKey?: string;
    /**
     * Nonnegative, finite reply budget in milliseconds from this message's arrival.
     * Bounds retired-socket draining until the SDK returns its reply/ack; the
     * five-second replacement-readiness grace always applies. Omitted or invalid
     * budgets do not extend that grace. This is not a handler-cancellation timeout.
     */
    readonly deadlineMs?: number;
    /** Delivery headers forwarded by the backend service. */
    readonly headers?: unknown;
};
/**
 * The frame the bot RETURNS from its `Activity` handler (SignalR client
 * results). For an invoke it carries the invoke `status`/`body`; for a one-way
 * activity it is a minimal post-handler acknowledgement (status 200, no body).
 */
export type ReplyFrame = {
    /** Always {@link SOCKET_MODE_PROTOCOL_VERSION}. */
    readonly protocolVersion: number;
    /** Echoes the inbound {@link SocketActivityEnvelope.envelopeId}. */
    readonly envelopeId?: string;
    /** Bot's client id, echoed for Teams backend service routing/validation. */
    readonly botKey?: string;
    /** HTTP-style status for the invoke result or delivery ack. */
    readonly status: number;
    /** Invoke response body; omitted for a bare acknowledgement. */
    readonly body?: unknown;
    /** When the reply was produced (epoch ms), for latency telemetry. */
    readonly ts?: number;
    /** When the envelope was received (epoch ms), echoed for telemetry. */
    readonly recvAt?: number;
};
/**
 * Abstraction over a single underlying socket connection (one negotiate +
 * SignalR session) so the server can be unit-tested without a live SignalR
 * connection. The default implementation wraps `@microsoft/signalr`.
 *
 * A connection represents exactly one generation: it never reconnects itself.
 * When the socket drops it reports {@link SocketConnectionHandlers.onClosed} and
 * becomes terminal; the {@link SocketModeAdapter} supervisor decides whether to
 * negotiate a fresh connection.
 */
export interface ISocketConnection {
    /**
     * Open the connection and resolve once the readiness contract (`SocketReady`)
     * is satisfied. Rejects if the socket fails to open, readiness is not reached
     * within the configured timeout, or `signal` aborts first.
     *
     * @param signal aborts an in-progress negotiate/connect/readiness wait when
     *   the server is stopping, so a late-completing connect can't come up after
     *   shutdown.
     */
    start(signal?: AbortSignal): Promise<void>;
    /** Close the connection. Safe to call more than once. */
    stop(): Promise<void>;
    /**
     * Lifetime, in seconds, of the negotiate access token backing this
     * connection (from the negotiate response), or `undefined` when unknown. The
     * supervisor uses it to proactively renegotiate before the token expires.
     */
    readonly expiresInSeconds?: number;
    /**
     * Local token-expiry deadline in epoch milliseconds, based on negotiate
     * response receipt plus its lifetime, before socket readiness. `undefined`
     * when unknown. Expiry disallows replacement headers, not inbound delivery.
     */
    readonly expiresAtMs?: number;
    /**
     * Server identity from this socket's first accepted `SocketReady` frame,
     * available before `onReady` and retained after close. `undefined` until
     * readiness or when the server omits the ID.
     */
    readonly connectionId?: string;
    /** Whether the transport is open. Only `true` permits a replacement header. */
    readonly isOpen?: boolean;
}
/**
 * Callbacks the server supplies to the underlying {@link ISocketConnection} so
 * the connection can drive the server without the server knowing the transport.
 */
export type SocketConnectionHandlers = {
    /**
     * Handle one inbound envelope and resolve with the reply frame to return over
     * client results, or `undefined` to send no reply. Settlement ends SDK drain
     * tracking; it does not confirm transport transmission or service receipt.
     */
    readonly onActivity: (envelope: SocketActivityEnvelope) => Promise<ReplyFrame | undefined>;
    /** Called when Teams backend service pushes the `SocketReady` readiness frame. */
    readonly onReady: (frame: SocketReadyFrame) => void;
    /**
     * Called once when the connection terminates (socket closed or lost). The
     * connection is terminal after this — the supervisor handles any reconnect by
     * building a new connection.
     */
    readonly onClosed: (error?: Error) => void;
};
/**
 * Everything the {@link ISocketConnection} needs to negotiate and open a single
 * connection.
 */
export type SocketConnectionContext = {
    /** Resolved regional negotiate URL. */
    readonly negotiateUrl: string;
    /** The app's shared HTTP client used for the negotiate request. */
    readonly client: HttpClient;
    /**
     * Acquire the Bot Framework access token used to authenticate the negotiate
     * request. Reuses the app's existing credentials.
     */
    readonly getBotToken: () => Promise<string>;
    /**
     * Planned-refresh predecessor's exact ID, checked just before the POST.
     * Return `undefined` if it has closed, its token expired, or its ID is unavailable.
     */
    readonly getConnectionIdToReplace?: () => string | undefined;
    /** Readiness timeout in milliseconds. */
    readonly readinessTimeoutMs: number;
};
