import { Request, RequestHandler } from 'express';
import { IncomingMessage } from 'node:http';
import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
import { JWTPayload } from 'jose';
export { CLIAuthProvider, CLIAuthProviderOptions, CLIClient, CivicAuthProvider, CivicAuthProviderOptions, DEFAULT_CALLBACK_PORT, DEFAULT_MCP_ROUTE, DEFAULT_SCOPES, DEFAULT_WELLKNOWN_URL, InMemoryTokenPersistence, PUBLIC_CIVIC_CLIENT_ID, RestartableStreamableHTTPClientTransport, TokenAuthProvider, TokenAuthProviderOptions, TokenPersistence } from './client/index.js';
import '@modelcontextprotocol/sdk/client/auth.js';
import '@modelcontextprotocol/sdk/shared/auth.js';
import '@modelcontextprotocol/sdk/client/sse.js';
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
import '@modelcontextprotocol/sdk/client/index.js';

interface CivicAuthOptions<TAuthInfo extends ExtendedAuthInfo, TRequest extends IncomingMessage = IncomingMessage> {
    /**
     * The URL to the auth server's well-known OIDC configuration
     * Defaults to https://auth.civic.com/oauth/.well-known/openid-configuration
     */
    wellKnownUrl?: string;
    /**
     * OAuth scopes to support
     * Defaults to ['openid', 'profile', 'email']
     */
    scopesSupported?: string[];
    /**
     * The issuer URL for the resource server
     * Defaults to the server's base URL
     */
    issuerUrl?: string | URL;
    /**
     * Base path for auth endpoints
     * Defaults to '/'
     */
    basePath?: string;
    /**
     * The MCP route to protect with authentication
     * Defaults to '/mcp'
     */
    mcpRoute?: string;
    /**
     * Optional callback to enrich the auth info with custom data
     * Called after successful token verification
     * @param authInfo The verified auth info from the token. Null if no token was provided.
     * @param request Optional request object that may contain headers or other data
     * @returns Enriched auth info with custom data
     */
    onLogin?: (authInfo: ExtendedAuthInfo | null, request?: TRequest) => Promise<TAuthInfo | null>;
    /**
     * Optional OAuth client ID / Tenant ID.
     * When set, the access token must include *either* a "client_id" field or "tid" field that matches it.
     */
    clientId?: string;
    /**
     * Whether to allow dynamic client registration by adding client ID as subdomain.
     * When true, the client ID will be added as a subdomain to the auth server URL.
     * When false (default), the auth server URL will be used as-is without subdomain prefixing.
     * Defaults to false.
     */
    allowDynamicClientRegistration?: boolean;
}
interface OIDCWellKnownConfiguration {
    issuer: string;
    authorization_endpoint: string;
    token_endpoint: string;
    jwks_uri: string;
    scopes_supported?: string[];
    response_types_supported?: string[];
    grant_types_supported?: string[];
    token_endpoint_auth_methods_supported?: string[];
    introspection_endpoint?: string;
    revocation_endpoint?: string;
    registration_endpoint?: string;
}
interface ExtendedAuthInfo extends AuthInfo {
    extra?: {
        sub?: string;
        email?: string;
        name?: string;
        picture?: string;
    };
}
/**
 * Custom error class for all authentication errors
 */
declare class AuthenticationError extends Error {
}
/**
 * Custom error class for JWT verification failures
 */
declare class JWTVerificationError extends AuthenticationError {
    originalError?: Error | undefined;
    constructor(message: string, originalError?: Error | undefined);
}
type AccessTokenPayload = JWTPayload & {
    client_id: string | undefined;
    tid: string | undefined;
};

/**
 * Core authentication functionality that can be used with any framework
 */
declare class McpServerAuth<TAuthInfo extends ExtendedAuthInfo, TRequest extends IncomingMessage = IncomingMessage> {
    private oidcConfig;
    private jwks;
    private options;
    private constructor();
    /**
     * Initialize the auth core by fetching OIDC configuration
     */
    static init<TAuthInfo extends ExtendedAuthInfo, TRequest extends IncomingMessage = IncomingMessage>(options?: CivicAuthOptions<TAuthInfo, TRequest>): Promise<McpServerAuth<TAuthInfo, TRequest>>;
    /**
     * Get the OAuth Protected Resource metadata
     * @param issuerUrl The issuer URL of the resource server (e.g., https://my-server.com)
     */
    getProtectedResourceMetadata(issuerUrl: string): {
        resource: string;
        authorization_servers: string[];
        scopes_supported: string[];
        bearer_methods_supported: string[];
    };
    /**
     * Create auth info from a token (or null) and request
     * @param token The JWT token (can be null)
     * @param payload The JWT payload if token was already verified
     * @param request Optional request object to pass to onLogin callback
     * @returns ExtendedAuthInfo if successful, null otherwise
     */
    private createAuthInfo;
    /**
     * Extract and verify bearer token from authorization header
     * @param authHeader The Authorization header value
     * @returns Object with token and payload if valid, throws if invalid token, returns null values if no token
     */
    private extractBearerToken;
    /**
     * Handle a request by extracting and verifying the bearer token
     * @param request The request object
     * @returns ExtendedAuthInfo if valid
     * @throws Error if authentication fails
     */
    handleRequest(request: TRequest): Promise<TAuthInfo>;
}

/**
 * Express middleware that configures an MCP server to use Civic Auth
 * as its authorization server.
 *
 * This middleware:
 * 1. Exposes /.well-known/oauth-protected-resource metadata
 * 2. Validates bearer tokens using Civic's JWKS
 * 3. Attaches user info to the request
 *
 * @param options Configuration options
 * @returns Express middleware
 */
declare function auth<TAuthInfo extends ExtendedAuthInfo>(options?: CivicAuthOptions<TAuthInfo, Request>): Promise<RequestHandler>;

export { type AccessTokenPayload, AuthenticationError, type CivicAuthOptions, type ExtendedAuthInfo, JWTVerificationError, McpServerAuth, type OIDCWellKnownConfiguration, auth };
