/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { HybridTokenStorage } from './token-storage/hybrid-token-storage.js';
const DEFAULT_SERVICE_NAME = 'llxprt-cli-mcp-oauth';
const EXPIRY_BUFFER_MS = 5 * 60 * 1000;
/**
 * Token storage wrapper that bridges the legacy static API with the new
 * shared TokenStorage interface used across the MCP stack. By default it
 * delegates to a HybridTokenStorage that prefers secure keychain storage but
 * transparently falls back to encrypted file storage when necessary.
 */
export class MCPOAuthTokenStorage {
    storage;
    static tokenStore = new HybridTokenStorage(DEFAULT_SERVICE_NAME);
    constructor(storage = MCPOAuthTokenStorage.tokenStore) {
        this.storage = storage;
    }
    /**
     * Swap out the underlying token store implementation. Useful for testing or
     * for embedding environments that need a custom persistence layer.
     */
    static setTokenStore(store) {
        this.tokenStore = store;
    }
    static getTokenStore() {
        return this.tokenStore;
    }
    /**
     * Legacy helper that loads all stored credentials.
     */
    static async loadTokens() {
        return (await this.tokenStore.getAllCredentials());
    }
    /**
     * Legacy helper that persists credentials for a server.
     */
    static async saveToken(serverName, token, clientId, tokenUrl, mcpServerUrl) {
        const credentials = this.createCredentials(serverName, token, clientId, tokenUrl, mcpServerUrl);
        await this.tokenStore.setCredentials(credentials);
    }
    /**
     * Legacy helper that retrieves credentials for a server.
     */
    static async getToken(serverName) {
        this.validateServerName(serverName);
        const credentials = await this.tokenStore.getCredentials(serverName);
        return credentials;
    }
    /**
     * Legacy helper that removes credentials for a server.
     */
    static async removeToken(serverName) {
        this.validateServerName(serverName);
        await this.tokenStore.deleteCredentials(serverName);
    }
    /**
     * Legacy helper that clears all persisted credentials.
     */
    static async clearAllTokens() {
        await this.tokenStore.clearAll();
    }
    /**
     * Determine whether a token is expired (with a buffer to avoid clock skew).
     */
    static isTokenExpired(token) {
        if (!token.expiresAt) {
            return false;
        }
        return Date.now() + EXPIRY_BUFFER_MS >= token.expiresAt;
    }
    /**
     * TokenStorage implementation - delegate all operations to the injected store.
     */
    async getCredentials(serverName) {
        MCPOAuthTokenStorage.validateServerName(serverName);
        return this.storage.getCredentials(serverName);
    }
    async setCredentials(credentials) {
        MCPOAuthTokenStorage.validateServerName(credentials.serverName);
        MCPOAuthTokenStorage.validateToken(credentials.token);
        await this.storage.setCredentials({
            ...credentials,
            updatedAt: credentials.updatedAt ?? Date.now(),
        });
    }
    async deleteCredentials(serverName) {
        MCPOAuthTokenStorage.validateServerName(serverName);
        await this.storage.deleteCredentials(serverName);
    }
    async listServers() {
        return this.storage.listServers();
    }
    async getAllCredentials() {
        return this.storage.getAllCredentials();
    }
    async clearAll() {
        await this.storage.clearAll();
    }
    /**
     * Convenience instance wrapper for legacy saveToken signature.
     */
    async saveToken(serverName, token, clientId, tokenUrl, mcpServerUrl) {
        const credentials = MCPOAuthTokenStorage.createCredentials(serverName, token, clientId, tokenUrl, mcpServerUrl);
        await this.storage.setCredentials(credentials);
    }
    /**
     * Convenience instance wrapper for legacy getToken signature.
     */
    async getToken(serverName) {
        const credentials = await this.getCredentials(serverName);
        return credentials;
    }
    async removeToken(serverName) {
        await this.deleteCredentials(serverName);
    }
    async loadTokens() {
        const tokens = await this.getAllCredentials();
        return tokens;
    }
    static validateServerName(serverName) {
        if (!serverName || typeof serverName !== 'string') {
            throw new Error('Server name must be a non-empty string');
        }
        if (serverName.trim().length === 0) {
            throw new Error('Server name must be a non-empty string');
        }
    }
    static validateToken(token) {
        if (!token || typeof token !== 'object') {
            throw new Error('Token must be a valid object');
        }
        if (!token.accessToken || typeof token.accessToken !== 'string') {
            throw new Error('Token must have a valid access token');
        }
        if (!token.tokenType || typeof token.tokenType !== 'string') {
            throw new Error('Token must have a valid token type');
        }
    }
    static createCredentials(serverName, token, clientId, tokenUrl, mcpServerUrl) {
        this.validateServerName(serverName);
        this.validateToken(token);
        return {
            serverName,
            token,
            clientId,
            tokenUrl,
            mcpServerUrl,
            updatedAt: Date.now(),
        };
    }
}
//# sourceMappingURL=oauth-token-storage.js.map