/**
 * @license
 * Copyright 2025 OElite Platform
 * SPDX-License-Identifier: Apache-2.0
 */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { BaseProvider } from './baseProvider.js';
import { ProviderType } from './types.js';
import { ANTHROPIC_MODELS } from './modelCatalog.js';
/**
 * Anthropic Claude provider implementation
 * Supports both API key and Claude Code subscription authentication
 */
export class AnthropicProvider extends BaseProvider {
    static DEFAULT_BASE_URL = 'https://api.anthropic.com';
    static API_VERSION = '2023-06-01';
    constructor(config) {
        super({
            ...config,
            type: ProviderType.ANTHROPIC,
            baseUrl: config.baseUrl || AnthropicProvider.DEFAULT_BASE_URL,
        });
    }
    async doInitialize() {
        // Check for Claude Code OAuth tokens first, then API key
        const hasOAuth = this.isUsingClaudeCodeSubscription();
        const apiKey = this.getEffectiveApiKey();
        if (!hasOAuth && !apiKey) {
            throw new Error('Anthropic authentication not configured. Please set ANTHROPIC_API_KEY or Claude Code OAuth tokens (CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_ACCESS_TOKEN, or CLAUDE_REFRESH_TOKEN)');
        }
        if (hasOAuth) {
            console.log('Claude Code subscription OAuth detected - using OAuth authentication');
        }
        else {
            console.log('Anthropic API key detected - using API key authentication');
        }
    }
    isConfigured() {
        const apiKey = this.getEffectiveApiKey();
        const hasClaudeCodeAuth = !!process.env['CLAUDE_CODE_OAUTH_TOKEN'] ||
            !!process.env['CLAUDE_REFRESH_TOKEN'] ||
            !!process.env['CLAUDE_ACCESS_TOKEN'];
        return !!apiKey || hasClaudeCodeAuth;
    }
    async getAvailableModels() {
        return ANTHROPIC_MODELS;
    }
    async doHealthCheck() {
        // Simple health check - try to get models
        await this.getAvailableModels();
    }
    async createCompletion(model, messages, options) {
        await this.validateModel(model);
        const headers = await this.getAuthHeaders();
        const baseUrl = this.getEffectiveBaseUrl();
        const response = await fetch(`${baseUrl}/v1/messages`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                ...headers,
                'anthropic-version': AnthropicProvider.API_VERSION,
                ...this.config.customHeaders,
            },
            body: JSON.stringify({
                model,
                messages: this.formatMessages(messages),
                max_tokens: options?.max_tokens || 4096,
                temperature: options?.temperature,
                top_p: options?.top_p,
                stream: false,
                ...options,
            }),
        });
        if (!response.ok) {
            const error = await response.text();
            throw new Error(`Anthropic API error: ${response.status} - ${error}`);
        }
        return await response.json();
    }
    async *createStreamingCompletion(model, messages, options) {
        await this.validateModel(model);
        const headers = await this.getAuthHeaders();
        const baseUrl = this.getEffectiveBaseUrl();
        const response = await fetch(`${baseUrl}/v1/messages`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                ...headers,
                'anthropic-version': AnthropicProvider.API_VERSION,
                ...this.config.customHeaders,
            },
            body: JSON.stringify({
                model,
                messages: this.formatMessages(messages),
                max_tokens: options?.max_tokens || 4096,
                temperature: options?.temperature,
                top_p: options?.top_p,
                stream: true,
                ...options,
            }),
        });
        if (!response.ok) {
            const error = await response.text();
            throw new Error(`Anthropic API error: ${response.status} - ${error}`);
        }
        if (!response.body) {
            throw new Error('No response body');
        }
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let buffer = '';
        try {
            while (true) {
                const { done, value } = await reader.read();
                if (done)
                    break;
                buffer += decoder.decode(value, { stream: true });
                const lines = buffer.split('\n');
                buffer = lines.pop() || '';
                for (const line of lines) {
                    if (line.trim() === '' || !line.startsWith('data: '))
                        continue;
                    const data = line.slice(6);
                    if (data === '[DONE]')
                        continue;
                    try {
                        const parsed = JSON.parse(data);
                        yield parsed;
                    }
                    catch {
                        // Skip invalid JSON
                    }
                }
            }
        }
        finally {
            reader.releaseLock();
        }
    }
    /**
     * Format messages for Anthropic API
     */
    formatMessages(messages) {
        return messages.map((msg) => ({
            role: msg.role === 'system' ? 'user' : msg.role,
            content: msg.content,
        }));
    }
    /**
     * Check if using Claude Code subscription
     */
    isUsingClaudeCodeSubscription() {
        return (!!process.env['CLAUDE_CODE_OAUTH_TOKEN'] ||
            !!process.env['CLAUDE_REFRESH_TOKEN'] ||
            !!process.env['CLAUDE_ACCESS_TOKEN']);
    }
    /**
     * Get authentication headers for API requests
     * Prefers OAuth tokens over API key when available
     */
    async getAuthHeaders() {
        // Prefer OAuth tokens if available
        const claudeCodeToken = process.env['CLAUDE_CODE_OAUTH_TOKEN'];
        const claudeAccessToken = process.env['CLAUDE_ACCESS_TOKEN'];
        if (claudeCodeToken) {
            return {
                Authorization: `Bearer ${claudeCodeToken}`,
            };
        }
        if (claudeAccessToken) {
            return {
                Authorization: `Bearer ${claudeAccessToken}`,
            };
        }
        // Fall back to API key
        const apiKey = this.getEffectiveApiKey();
        if (!apiKey) {
            throw new Error('No authentication credentials configured');
        }
        return {
            'x-api-key': apiKey,
        };
    }
    /**
     * Get Claude Code OAuth information
     */
    getClaudeCodeAuthInfo() {
        return {
            hasOAuthToken: !!process.env['CLAUDE_CODE_OAUTH_TOKEN'],
            hasRefreshToken: !!process.env['CLAUDE_REFRESH_TOKEN'],
            hasAccessToken: !!process.env['CLAUDE_ACCESS_TOKEN'],
        };
    }
}
//# sourceMappingURL=anthropicProvider.js.map