import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
vi.mock('./local-oauth-callback.js', () => ({
    startLocalOAuthCallback: vi.fn(),
}));
import * as coreModule from '@vybestack/llxprt-code-core';
import { AnthropicOAuthProvider } from './anthropic-oauth-provider.js';
import { startLocalOAuthCallback } from './local-oauth-callback.js';
const startLocalOAuthCallbackMock = vi.mocked(startLocalOAuthCallback);
const openBrowserArgs = [];
describe('AnthropicOAuthProvider local callback flow', () => {
    let provider;
    let tokenStore;
    let deviceFlow;
    let shouldLaunchBrowserSpy;
    beforeEach(() => {
        openBrowserArgs.length = 0;
        startLocalOAuthCallbackMock.mockReset();
        vi.spyOn(global.console, 'log').mockImplementation(() => { });
        const saveToken = vi.fn(async (_provider, _token) => { });
        tokenStore = {
            saveToken,
            getToken: vi.fn(async () => null),
            removeToken: vi.fn(async () => undefined),
            listProviders: vi.fn(async () => []),
            listBuckets: vi.fn(async () => ['default']),
            getBucketStats: vi.fn(async () => null),
        };
        provider = new AnthropicOAuthProvider(tokenStore);
        deviceFlow = provider.deviceFlow;
        deviceFlow.initiateDeviceFlow = vi.fn(async () => ({
            verification_uri: 'https://console.anthropic.com/oauth/authorize',
            verification_uri_complete: 'https://claude.ai/oauth/authorize?redirect_uri=https%3A%2F%2Fconsole.anthropic.com%2Foauth%2Fcode',
            user_code: 'CODE123',
            device_code: 'device-code',
            expires_in: 1800,
            interval: 5,
        }));
        deviceFlow.getState = vi
            .fn()
            .mockReturnValue('generated-state');
        deviceFlow.buildAuthorizationUrl = vi
            .fn()
            .mockImplementation((redirectUri) => `https://claude.ai/oauth/authorize?redirect_uri=${encodeURIComponent(redirectUri)}&code=true`);
        deviceFlow.exchangeCodeForToken = vi.fn(async () => ({
            token_type: 'Bearer',
            access_token: 'local-token',
            expiry: Math.floor(Date.now() / 1000) + 3600,
            scope: null,
        }));
        vi.spyOn(coreModule, 'openBrowserSecurely').mockImplementation(async (url) => {
            openBrowserArgs.push(url);
        });
        shouldLaunchBrowserSpy = vi
            .spyOn(coreModule, 'shouldLaunchBrowser')
            .mockReturnValue(true);
    });
    afterEach(() => {
        vi.restoreAllMocks();
        delete global.__oauth_needs_code;
        delete global.__oauth_provider;
    });
    it('uses local callback when browser launch is available', async () => {
        const waitForCallback = vi
            .fn()
            .mockResolvedValue({ code: 'auth-code', state: 'generated-state' });
        const shutdown = vi.fn().mockResolvedValue(undefined);
        startLocalOAuthCallbackMock.mockResolvedValue({
            redirectUri: 'http://localhost:8765/callback',
            waitForCallback,
            shutdown,
        });
        await provider.initiateAuth();
        expect(startLocalOAuthCallbackMock).toHaveBeenCalledWith(expect.objectContaining({ state: 'generated-state' }));
        expect(openBrowserArgs.some((url) => url.includes('localhost'))).toBe(true);
        expect(tokenStore.saveToken).toHaveBeenCalledWith('anthropic', expect.objectContaining({ access_token: 'local-token' }));
        expect(global.__oauth_needs_code).toBe(undefined);
        expect(waitForCallback).toHaveBeenCalled();
        expect(shutdown).toHaveBeenCalled();
    });
    it('falls back to manual entry when local callback fails', async () => {
        startLocalOAuthCallbackMock.mockRejectedValue(new Error('callback unavailable'));
        shouldLaunchBrowserSpy.mockReturnValue(true);
        const manualPromise = provider.initiateAuth();
        await new Promise((resolve) => setTimeout(resolve, 0));
        provider.cancelAuth();
        await manualPromise.catch(() => undefined);
        expect(startLocalOAuthCallbackMock).toHaveBeenCalled();
        expect(global.__oauth_needs_code).toBe(true);
    });
});
//# sourceMappingURL=anthropic-oauth-provider.local-flow.spec.js.map