/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { DebugLogger } from '@vybestack/llxprt-code-core';
const logger = new DebugLogger('llxprt:auth:multi-bucket');
/**
 * Multi-bucket authenticator for OAuth flows
 *
 * Handles sequential authentication of multiple OAuth buckets with:
 * - Timing controls (delay or prompt-based)
 * - Browser auto-open control
 * - User notifications
 * - Partial cancellation support
 */
export class MultiBucketAuthenticator {
    onAuthBucket;
    onPrompt;
    onDelay;
    getEphemeralSetting;
    cancelled = false;
    constructor(onAuthBucket, onPrompt, onDelay, getEphemeralSetting = () => undefined) {
        this.onAuthBucket = onAuthBucket;
        this.onPrompt = onPrompt;
        this.onDelay = onDelay;
        this.getEphemeralSetting = getEphemeralSetting;
    }
    /**
     * Create authenticator from callbacks object
     */
    static fromCallbacks(callbacks) {
        return new MultiBucketAuthenticator(callbacks.onAuthBucket, callbacks.onPrompt, callbacks.onDelay, callbacks.getEphemeralSetting);
    }
    /**
     * Authenticate multiple buckets sequentially with timing controls
     */
    async authenticateMultipleBuckets(options) {
        const { provider, buckets } = options;
        logger.debug('Starting multi-bucket authentication', {
            provider,
            bucketCount: buckets.length,
        });
        if (buckets.length === 0) {
            return {
                authenticatedBuckets: [],
                failedBuckets: [],
                cancelled: false,
            };
        }
        const authenticatedBuckets = [];
        const failedBuckets = [];
        let firstError;
        const effectiveDelay = options.delay ??
            this.getEphemeralSetting('auth-bucket-delay') ??
            5000;
        const rawShowPromptSetting = this.getEphemeralSetting('auth-bucket-prompt');
        const effectiveShowPrompt = options.showPrompt ?? rawShowPromptSetting ?? false;
        logger.debug('Multi-bucket auth settings', {
            optionsShowPrompt: options.showPrompt,
            rawShowPromptSetting,
            effectiveShowPrompt,
            effectiveDelay,
        });
        for (let i = 0; i < buckets.length; i++) {
            if (this.cancelled) {
                logger.debug('Multi-bucket auth cancelled', {
                    authenticated: authenticatedBuckets.length,
                    remaining: buckets.length - i,
                });
                failedBuckets.push(...buckets.slice(i));
                return {
                    authenticatedBuckets,
                    failedBuckets,
                    cancelled: true,
                    error: firstError,
                };
            }
            const bucket = buckets[i];
            if (effectiveShowPrompt) {
                const shouldContinue = await this.onPrompt(provider, bucket);
                if (!shouldContinue) {
                    logger.debug('User cancelled at prompt', { bucket });
                    failedBuckets.push(...buckets.slice(i));
                    return {
                        authenticatedBuckets,
                        failedBuckets,
                        cancelled: true,
                        error: firstError,
                    };
                }
            }
            else {
                // Apply delay before EVERY bucket (including first) so user can pick browser
                await this.onDelay(effectiveDelay, bucket);
            }
            try {
                await this.onAuthBucket(provider, bucket, i + 1, buckets.length);
                authenticatedBuckets.push(bucket);
            }
            catch (error) {
                const errorMessage = error instanceof Error ? error.message : String(error);
                logger.error('Bucket authentication failed', {
                    bucket,
                    error: errorMessage,
                });
                failedBuckets.push(bucket);
                if (!firstError) {
                    firstError = errorMessage;
                }
            }
        }
        const result = {
            authenticatedBuckets,
            failedBuckets,
            cancelled: false,
            error: firstError,
        };
        logger.debug('Multi-bucket auth complete', {
            authenticated: authenticatedBuckets.length,
            failed: failedBuckets.length,
        });
        return result;
    }
    /**
     * Request cancellation of multi-bucket auth flow
     */
    cancel() {
        logger.debug('Multi-bucket auth cancellation requested');
        this.cancelled = true;
    }
}
//# sourceMappingURL=MultiBucketAuthenticator.js.map