import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
import { OAuthTokens, OAuthClientInformation, OAuthClientMetadata } from '@modelcontextprotocol/sdk/shared/auth.js';
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
import { StreamableHTTPClientTransport, StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

declare const DEFAULT_WELLKNOWN_URL = "https://auth.civic.com/oauth/.well-known/openid-configuration";
/**
 * Default scope for OAuth authentication
 */
declare const DEFAULT_SCOPES: string[];
/**
 * Default callback port for CLI authentication flow
 */
declare const DEFAULT_CALLBACK_PORT = 8080;
declare const DEFAULT_MCP_ROUTE = "/mcp";
declare const PUBLIC_CIVIC_CLIENT_ID = "12220cf4-1a9a-4964-8eb7-7c6d7d049f34";

/**
 * Interface for token persistence strategies
 */
interface TokenPersistence {
    /**
     * Save tokens to persistence storage
     */
    saveTokens(tokens: OAuthTokens): Promise<void> | void;
    /**
     * Load tokens from persistence storage
     */
    loadTokens(): Promise<OAuthTokens | undefined> | OAuthTokens | undefined;
    /**
     * Clear stored tokens
     */
    clearTokens(): Promise<void> | void;
}

/**
 * In-memory token persistence strategy
 * Tokens are stored in memory and lost when the process exits
 */
declare class InMemoryTokenPersistence implements TokenPersistence {
    private tokens;
    saveTokens(tokens: OAuthTokens): void;
    loadTokens(): OAuthTokens | undefined;
    clearTokens(): void;
}

interface CivicAuthProviderOptions {
    /**
     * Client secret for OAuth flows that don't support PKCE.
     * Optional - only needed for auth servers that require client authentication.
     */
    clientSecret?: string;
    /**
     * Token persistence strategy to use for storing/retrieving tokens.
     * Defaults to in-memory persistence if not provided.
     */
    tokenPersistence?: TokenPersistence;
}
/**
 * Abstract base class for Civic auth providers
 */
declare abstract class CivicAuthProvider implements OAuthClientProvider {
    protected clientSecret?: string;
    protected tokenPersistence: TokenPersistence;
    constructor(options: CivicAuthProviderOptions);
    abstract clientInformation(): OAuthClientInformation | Promise<OAuthClientInformation | undefined> | undefined;
    abstract get clientMetadata(): OAuthClientMetadata;
    abstract codeVerifier(): string | Promise<string>;
    abstract get redirectUrl(): string | URL;
    abstract saveCodeVerifier(codeVerifier: string): void;
    saveTokens(tokens: OAuthTokens): void | Promise<void>;
    /**
     * Returns the stored tokens
     */
    tokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;
    /**
     * Clears the stored tokens
     */
    clearTokens(): void | Promise<void>;
    abstract redirectToAuthorization(authorizationUrl: URL): void | Promise<void>;
}

interface CLIAuthProviderOptions extends CivicAuthProviderOptions {
    clientId: string;
    scope?: string;
    callbackPort?: number;
    enablePortFallback?: boolean;
    successHtml?: string;
    errorHtml?: string;
    authTimeoutMs?: number;
}
/**
 * CLI Auth Provider for MCP
 * Opens authorization URL in default browser and stores tokens in memory
 */
declare class CLIAuthProvider extends CivicAuthProvider {
    private storedCodeVerifier;
    private clientId;
    private scope;
    private callbackPort;
    private enablePortFallback;
    private authTimeoutMs;
    private successHtml;
    private errorHtml;
    private callbackServer;
    private authorizationCodePromise;
    private authorizationCodeResolve;
    private authorizationCodeReject;
    private transport;
    private serverTimeout;
    constructor(options: CLIAuthProviderOptions);
    clientInformation(): OAuthClientInformation | Promise<OAuthClientInformation | undefined> | undefined;
    get clientMetadata(): OAuthClientMetadata;
    codeVerifier(): string | Promise<string>;
    redirectToAuthorization(authorizationUrl: URL): Promise<void>;
    /**
     * Registers the transport with the auth provider so that we can call finishAuth when the code is received.
     * @param transport
     */
    registerTransport(transport: SSEClientTransport | StreamableHTTPClientTransport): void;
    get redirectUrl(): string | URL;
    saveCodeVerifier(codeVerifier: string): void;
    private getCallbackUrl;
    /**
     * Listen on Port Promise
     * @param server
     * @param port
     * @private port that is being listened on.
     */
    private listenOnPort;
    /**
     * Starts a local HTTP server to handle the OAuth callback with port fallback support
     * @returns The actual port number if different from the configured port, undefined otherwise
     */
    private startCallbackServer;
    /**
     * Resets the instance to its post-initialization state
     * Stops any active server, clears timeouts
     */
    private cleanup;
    /**
     * Waits for the authorization code from the callback
     */
    waitForAuthorizationCode(): Promise<string>;
    private openInBrowser;
}

/**
 * Configuration options for TokenAuthProvider
 */
interface TokenAuthProviderOptions extends CivicAuthProviderOptions {
    /**
     * OAuth tokens to use for authentication
     */
    tokens: OAuthTokens;
}
/**
 * Authentication provider for pre-obtained tokens.
 * Use this when you already have access tokens from an external OAuth flow
 * and want to use them directly with the MCP client.
 */
declare class TokenAuthProvider extends CivicAuthProvider {
    /**
     * Create a new TokenAuthProvider
     * @param tokenOrOptions - Either a token string or full options object
     */
    constructor(tokenOrOptions: string | TokenAuthProviderOptions);
    get redirectUrl(): string | URL;
    get clientMetadata(): OAuthClientMetadata;
    clientInformation(): OAuthClientInformation | undefined;
    redirectToAuthorization(_authorizationUrl: URL): void;
    saveCodeVerifier(_codeVerifier: string): void;
    codeVerifier(): string;
}

type RestartableStreamableHTTPClientTransportOpts = StreamableHTTPClientTransportOptions & {
    authProvider: CLIAuthProvider;
};
/**
 * A transport that extends StreamableHTTPClientTransport to support restarting
 * the connection after authentication. This is particularly useful when
 * implementing authentication flows that require redirection and reconnection.
 */
declare class RestartableStreamableHTTPClientTransport extends StreamableHTTPClientTransport {
    private _cliAuthProvider;
    constructor(url: URL, opts: RestartableStreamableHTTPClientTransportOpts);
    get authProvider(): CLIAuthProvider;
    /**
     * Extends the start method to properly handle reconnection.
     * If the transport has already been started, it will disconnect first,
     * then start again to establish a fresh connection.
     */
    start(): Promise<void>;
    close(): Promise<void>;
}

/**
 * MCP Client with built-in CLI authentication support
 * Handles the OAuth flow automatically and retries connection after auth
 */
declare class CLIClient extends Client {
    /**
     * Connect to MCP server with automatic authentication handling
     * If the first connection fails due to auth, it will wait for the OAuth flow
     * to complete and then retry the connection
     */
    connect(transport: RestartableStreamableHTTPClientTransport): Promise<void>;
}

export { CLIAuthProvider, type CLIAuthProviderOptions, CLIClient, CivicAuthProvider, type CivicAuthProviderOptions, DEFAULT_CALLBACK_PORT, DEFAULT_MCP_ROUTE, DEFAULT_SCOPES, DEFAULT_WELLKNOWN_URL, InMemoryTokenPersistence, PUBLIC_CIVIC_CLIENT_ID, RestartableStreamableHTTPClientTransport, TokenAuthProvider, type TokenAuthProviderOptions, type TokenPersistence };
