/**
 * The `SaasBackend` PORT — the dependency-inversion seam of the SaaS connector
 * bridge.
 *
 * The whole point of this file is to name, in *our* vocabulary, the minimal
 * surface the rest of the bridge (the gateway, the scope planner, the remote-tool
 * builder) is allowed to lean on. It deliberately knows nothing about
 * `@composio/core`: every shape below is ours, hand-shaped to be exactly what the
 * core logic consumes and no more. A single adapter elsewhere will satisfy this
 * port by translating to and from the vendor SDK — that adapter is the *only*
 * place the third-party catalog leaks in. Everything that imports this file talks
 * to an interface, never to a vendor.
 *
 * The six methods cover the three jobs the bridge does: **discovery**
 * ({@link SaasBackend.listToolkits}, {@link SaasBackend.listTools}), **execution**
 * ({@link SaasBackend.execute}), and **linking / auth**
 * ({@link SaasBackend.listConnectedAccounts}, {@link SaasBackend.initiateConnection},
 * {@link SaasBackend.checkConnection}). Each returns one of the plain record types
 * defined here, so a fake backend for tests is a few object literals away.
 */
import type { JsonSchema } from "../../../llmgateway/contract";
/**
 * A connectable third-party product (GitHub, Gmail, Slack, …) as the catalog
 * advertises it. `slug` is the stable machine identifier the rest of the bridge
 * keys on; `name` and `description` are for the model and humans. `connected`,
 * when the backend can cheaply tell, summarizes whether any account is linked.
 */
export interface ToolkitInfo {
    /** Stable machine identifier for the toolkit (e.g. `"github"`). */
    readonly slug: string;
    /** Human-facing toolkit name. */
    readonly name: string;
    /** One-line summary of what the toolkit covers. */
    readonly description: string;
    /** Whether the backend believes at least one account is currently linked. */
    readonly connected?: boolean;
}
/**
 * One callable operation exposed by a toolkit, in the shape the bridge needs to
 * mint a native agent tool from it. `inputSchema` is a JSON Schema object —
 * structurally the same `JsonSchema` the gateway hands the model for every other
 * tool — so a remote tool advertises its parameters identically to a built-in.
 */
export interface RemoteTool {
    /** The fully-qualified operation slug used to invoke it (e.g. `"GITHUB_CREATE_ISSUE"`). */
    readonly name: string;
    /** The toolkit this operation belongs to (its {@link ToolkitInfo.slug}). */
    readonly toolkit: string;
    /** Model-facing description of the operation. */
    readonly description: string;
    /** JSON-Schema object describing the operation's parameters. */
    readonly inputSchema: JsonSchema;
}
/**
 * The outcome of running a {@link RemoteTool}.
 *
 * `ok` is the success/failure discriminant the bridge maps onto a tool result's
 * `isError`. `data` is the raw structured payload the operation returned (shown to
 * the model as JSON); `error`, when present, is a single human-readable line. A
 * backend that has a correlation/log handle may surface it as `logId` for tracing.
 */
export interface RemoteResult {
    /** True when the operation completed without an error. */
    readonly ok: boolean;
    /** The structured payload the operation produced, if any. */
    readonly data?: unknown;
    /** A single-line failure description when `ok` is false. */
    readonly error?: string;
    /** Optional backend-side correlation handle for tracing. */
    readonly logId?: string;
}
/**
 * A credential link the user has established with a toolkit. The bridge inspects
 * these to decide whether a connect flow is needed and which account to execute
 * under. `status` is normalized to our small {@link ConnectionState.status}
 * vocabulary by the adapter, not the vendor's enum.
 */
export interface ConnectedAccount {
    /** The account's stable identifier, used as the `accountId` on execute. */
    readonly id: string;
    /** The toolkit slug this account links. */
    readonly toolkit: string;
    /** Normalized lifecycle status of the link. */
    readonly status: ConnectionStatus;
    /** ISO-8601 timestamp of the most recent update, when the backend reports it. */
    readonly updatedAt?: string;
}
/**
 * The normalized lifecycle of a connection, ours rather than the vendor's. The
 * adapter folds the catalog's richer enum down to these four buckets so the core
 * logic only ever branches on a closed set it owns.
 */
export type ConnectionStatus = "active" | "pending" | "expired" | "failed";
/**
 * What {@link SaasBackend.initiateConnection} hands back: a freshly opened (or
 * re-opened) connection attempt. `authUrl` is the actionable redirect the model
 * should surface to the user when present; `id` is the request handle to poll via
 * {@link SaasBackend.checkConnection}.
 */
export interface ConnectionRequest {
    /** Identifier of the connection request, pollable for state. */
    readonly id: string;
    /** The toolkit the request targets. */
    readonly toolkit: string;
    /** Current normalized status at the moment the request was created. */
    readonly status: ConnectionStatus;
    /** OAuth/redirect URL the user must visit to authorize, when one applies. */
    readonly authUrl?: string;
}
/**
 * A point-in-time snapshot of a connection request's progress, returned by
 * {@link SaasBackend.checkConnection}. Once `status` reaches `"active"` the
 * resulting `accountId` is the linked account to execute under.
 */
export interface ConnectionState {
    /** The request identifier this snapshot describes. */
    readonly id: string;
    /** Normalized status at the time of the check. */
    readonly status: ConnectionStatus;
    /** The connected-account id, present once the link has gone active. */
    readonly accountId?: string;
    /** A still-pending authorization URL, if the user has yet to act. */
    readonly authUrl?: string;
}
/** Per-call execution knobs the gateway threads down to the backend. */
export interface ExecuteOptions {
    /** Pin execution to a specific connected account; omit to let the backend pick. */
    readonly accountId?: string;
}
/** Optional inputs for opening a connection request. */
export interface InitiateOptions {
    /** Reuse a known auth-config rather than the toolkit's default, when supported. */
    readonly authConfigId?: string;
    /** Caller-supplied redirect to return the user to after authorizing. */
    readonly callbackUrl?: string;
}
/**
 * The minimal backend surface the SaaS bridge depends on.
 *
 * This is the inverted dependency: core modules accept a `SaasBackend` and never
 * reach for the vendor SDK. One adapter implements it; tests implement it with
 * plain objects.
 */
export interface SaasBackend {
    /** Enumerate the connectable toolkits the catalog offers. */
    listToolkits(): Promise<ToolkitInfo[]>;
    /** Enumerate the callable operations exposed by one toolkit. */
    listTools(toolkit: string): Promise<RemoteTool[]>;
    /** Run a single operation by its slug, with already-parsed arguments. */
    execute(toolName: string, args: unknown, opts: ExecuteOptions): Promise<RemoteResult>;
    /** List the user's existing credential links across toolkits. */
    listConnectedAccounts(): Promise<ConnectedAccount[]>;
    /** Begin (or re-open) a connection/authorization flow for a toolkit. */
    initiateConnection(toolkit: string, opts?: InitiateOptions): Promise<ConnectionRequest>;
    /** Poll a previously initiated connection request for its current state. */
    checkConnection(id: string): Promise<ConnectionState>;
}
