/**
 * Google Chat Messenger Adapter
 *
 * Messenger adapter for Google Chat supporting three connection modes:
 * 1. **Webhook mode** — post messages via an incoming webhook URL (send-only)
 * 2. **Service account mode** — send messages via the Chat API (send-only)
 * 3. **Pub/Sub mode** — pull incoming messages from a Cloud Pub/Sub subscription
 *    and reply via the Chat API (bidirectional, thread-aware)
 *
 * In Pub/Sub mode, a Google Chat App is configured to publish events to a
 * Pub/Sub topic. Crewly pulls from the subscription, processes MESSAGE events,
 * and replies in the same thread via the Chat API.
 *
 * @module services/messaging/adapters/google-chat-messenger.adapter
 */
import { MessengerAdapter, MessengerPlatform, IncomingMessage } from '../messenger-adapter.interface.js';
/** Authentication mode — how OAuth2 tokens are obtained */
export type GoogleChatAuthMode = 'service_account' | 'adc';
/**
 * ADC (Application Default Credentials) JSON file shape.
 * Created by `gcloud auth application-default login`.
 */
interface AdcCredentials {
    client_id: string;
    client_secret: string;
    refresh_token: string;
    type: string;
}
/**
 * Callback type for incoming messages from Pub/Sub pull.
 */
export type GoogleChatIncomingCallback = (msg: IncomingMessage) => void;
/**
 * Messenger adapter for Google Chat with Pub/Sub support.
 *
 * Supports webhook, service-account, and pubsub modes.
 * Pub/Sub mode enables bidirectional communication with thread tracking.
 */
export declare class GoogleChatMessengerAdapter implements MessengerAdapter {
    readonly platform: MessengerPlatform;
    /** Current connection mode */
    private mode;
    /** Webhook URL for posting messages (webhook mode) */
    private webhookUrl;
    /** Service account key JSON string */
    private serviceAccountKey;
    /** Authentication mode: service_account (JWT) or adc (refresh token) */
    private authMode;
    /** ADC credentials (parsed from application_default_credentials.json) */
    private adcCredentials;
    /** Access token obtained from service account or ADC (cached) */
    private accessToken;
    /** Access token expiry timestamp */
    private tokenExpiresAt;
    /** OAuth2 scopes for the current mode */
    private tokenScopes;
    /** Pending token refresh promise to deduplicate concurrent requests (RL2) */
    private pendingTokenRefresh;
    /** Full Pub/Sub subscription resource name (e.g. projects/PROJECT/subscriptions/SUB) */
    private subscriptionName;
    /** GCP project ID (for Pub/Sub mode) */
    private projectId;
    /** Pub/Sub pull interval timer */
    private pullIntervalTimer;
    /** Callback for incoming messages */
    private onIncomingMessage;
    /** Service account email for impersonation (ADC mode) */
    private serviceAccountEmail;
    /** Impersonated SA token (separate from user ADC token) */
    private saAccessToken;
    /** Impersonated SA token expiry timestamp */
    private saTokenExpiresAt;
    /**
     * Recent send deduplication cache.
     * Key: `${space}:${threadId}:${contentPrefix}`, value: timestamp (epoch ms).
     * Prevents the same message being sent twice within DEDUP_WINDOW_MS (e.g. when
     * both the auto-route and a manual reply-gchat call fire for the same response).
     */
    private recentSends;
    /** Deduplication window in milliseconds */
    private static readonly DEDUP_WINDOW_MS;
    /** Consecutive pull failure count */
    private consecutiveFailures;
    /** Whether the pull loop is paused due to failures */
    private pullPaused;
    /** Timestamp of the last successful pull (epoch ms) */
    private lastPullAt;
    /**
     * Initialize the adapter with the provided credentials.
     *
     * Detects mode based on provided config fields:
     * - `webhookUrl` → webhook mode
     * - `serviceAccountKey` + `projectId` + `subscriptionName` → pubsub mode
     * - `serviceAccountKey` alone → service-account mode
     *
     * @param config - Configuration object with credentials
     * @throws Error if credentials are invalid or missing
     */
    initialize(config: Record<string, unknown>): Promise<void>;
    /**
     * Send a text message to a Google Chat space.
     *
     * In webhook mode, the `channel` parameter is ignored (webhook URL determines the space).
     * In service-account/pubsub mode, `channel` is the space name (e.g., "spaces/AAAA...").
     *
     * @param channel - Google Chat space name (used in service-account/pubsub mode)
     * @param text - Message content
     * @param options - Optional send options (threadId for threaded replies)
     * @throws Error if adapter is not initialized or send fails
     */
    sendMessage(channel: string, text: string, options?: {
        threadId?: string;
    }): Promise<void>;
    /**
     * Get the current connection status.
     *
     * @returns Status object with connected flag, platform, and mode details
     */
    getStatus(): {
        connected: boolean;
        platform: MessengerPlatform;
        details?: Record<string, unknown>;
    };
    /**
     * Disconnect by clearing stored credentials and stopping the pull loop.
     */
    disconnect(): Promise<void>;
    /**
     * Add an emoji reaction to a Google Chat message.
     *
     * Only works in service-account/pubsub mode — webhook mode does not support the
     * reactions API. Calls `spaces.messages.reactions.create`.
     *
     * @param messageName - Full message resource name (e.g., "spaces/xxx/messages/yyy")
     * @param emoji - Unicode emoji character (e.g., "👀", "✅")
     */
    addReaction(messageName: string, emoji: string): Promise<void>;
    /**
     * Start the Pub/Sub pull loop that periodically fetches messages.
     */
    private startPubSubPull;
    /**
     * Stop the Pub/Sub pull loop.
     */
    private stopPubSubPull;
    /**
     * Pull messages from the Pub/Sub subscription, process them, and acknowledge.
     *
     * Each message is a base64-encoded Google Chat event JSON. Only MESSAGE-type
     * events are forwarded to the incoming message callback. All messages are
     * acknowledged regardless of type to prevent redelivery.
     */
    pullMessages(): Promise<number>;
    /**
     * Process a Google Chat event and forward MESSAGE events to the callback.
     *
     * Supports two payload formats:
     * - **Legacy (v1)**: `{ type: 'MESSAGE', message: { text, sender, thread }, space }`
     * - **v2**: `{ commonEventObject: {...}, chat: { messagePayload: { message: {...}, space: {...} } } }`
     *
     * Both formats are normalized into the same IncomingMessage shape.
     *
     * @param event - Parsed Google Chat event payload (legacy or v2)
     */
    private processChatEvent;
    /**
     * Acknowledge processed messages to prevent redelivery.
     *
     * @param ackIds - Array of ack IDs from the pull response
     */
    private acknowledgeMessages;
    /**
     * Send a message via incoming webhook URL.
     *
     * @param text - Message text
     * @param threadKey - Optional thread key for threaded replies
     */
    private sendViaWebhook;
    /**
     * Send a message via the Google Chat REST API using service account credentials.
     *
     * When a threadId (thread name) is provided, the reply is posted to the same
     * thread. This enables conversational thread tracking for Pub/Sub mode.
     *
     * @param space - Space name (e.g., "spaces/AAAA...")
     * @param text - Message text
     * @param threadName - Optional full thread name (e.g., "spaces/SPACE/threads/THREAD")
     */
    private sendViaApi;
    /**
     * Split a message into chunks that fit within Google Chat's character limit.
     *
     * Splits on double-newline paragraph boundaries when possible. Falls back to
     * single-newline, then hard truncation at maxLength.
     *
     * @param text - The full message text to split
     * @param maxLength - Maximum characters per chunk (default 4000)
     * @returns Array of text chunks, each within maxLength
     */
    static splitMessage(text: string, maxLength?: number): string[];
    /**
     * Get a valid access token, refreshing if needed.
     *
     * Uses JWT-based OAuth2 for service accounts, or refresh_token flow for ADC.
     * The scope includes Pub/Sub when in pubsub mode.
     *
     * @returns Valid access token string
     */
    getAccessToken(): Promise<string>;
    /**
     * Perform the actual token refresh.
     *
     * Dispatches to the appropriate flow based on authMode:
     * - `service_account`: JWT-based OAuth2 flow with SA private key
     * - `adc`: Refresh token flow using ADC credentials
     *
     * @returns Fresh access token string
     */
    private refreshAccessToken;
    /**
     * Refresh access token via JWT-based OAuth2 flow (service account).
     *
     * @returns Fresh access token string
     */
    private refreshAccessTokenViaJwt;
    /**
     * Refresh access token via ADC (Application Default Credentials).
     *
     * Uses the refresh_token from the ADC JSON file to obtain a new access token
     * from Google's OAuth2 token endpoint. This supports credentials created by
     * `gcloud auth application-default login`.
     *
     * When `serviceAccountEmail` is configured, the ADC user token is used to
     * impersonate the service account via the IAM Credentials API, producing a
     * token with `chat.bot` and `pubsub` scopes that the Chat API accepts.
     *
     * @returns Fresh access token string (impersonated SA token if configured, else user token)
     */
    private refreshAccessTokenViaAdc;
    /**
     * Impersonate a service account using the IAM Credentials API.
     *
     * Uses the user's ADC access token to call `generateAccessToken` on the
     * target service account, producing a token with `chat.bot` and `pubsub`
     * scopes. The user must have the `Service Account Token Creator` IAM role.
     *
     * @param userToken - ADC user access token for authorization
     * @returns Impersonated service account access token
     * @throws Error if impersonation fails (e.g., missing IAM role)
     */
    private impersonateServiceAccount;
    /**
     * Build auth headers for Google API requests.
     *
     * When using ADC auth mode, adds x-goog-user-project header to set the
     * billing/quota project. Without this header, ADC requests fail with
     * 403 PERMISSION_DENIED because Google cannot determine which project
     * should be billed for the API usage.
     *
     * @param token - OAuth2 access token
     * @returns Headers object with Authorization, Content-Type, and optional quota project
     */
    private getAuthHeaders;
    /**
     * Validate a service account key JSON string.
     *
     * @param key - JSON string of the service account key
     * @throws Error if the key is invalid
     */
    private validateServiceAccountKey;
    /**
     * Load ADC (Application Default Credentials) from the filesystem.
     *
     * Checks (in order):
     * 1. `GOOGLE_APPLICATION_CREDENTIALS` environment variable (custom path)
     * 2. Default gcloud ADC path: `~/.config/gcloud/application_default_credentials.json`
     *
     * @returns Parsed ADC credentials
     * @throws Error if the ADC file is not found or invalid
     */
    loadAdcCredentials(): Promise<AdcCredentials>;
    /**
     * Reset all internal state to defaults.
     */
    private resetState;
}
export {};
//# sourceMappingURL=google-chat-messenger.adapter.d.ts.map