// Copyright (c) 2026 defconxt. All rights reserved.
// Licensed under AGPL-3.0 — see LICENSE file for details.
// NERF is a trademark of defconxt.

/**
 * client.js — LLM client factory for NERF gateway.
 *
 * All LLM access goes through pi-mono's pi-ai unified API, which supports
 * 26+ providers (Anthropic, OpenAI, Google, Ollama, OpenRouter, Azure, etc.)
 * through a single interface.
 *
 * Returns an Anthropic-SDK-compatible client ({client, model}) that
 * NERF's gateway and auto-mode runtime consume.
 *
 * All SDK imports are lazy (dynamic import()) to preserve cold start <200ms.
 * API keys are treated as opaque strings — never logged.
 *
 * @module gateway/client
 */

import { makePiClient } from './client-pi.js';

const debug = process.env.NERF_DEBUG === '1'
  ? (/** @type {string} */ msg) => process.stderr.write(`[bridge:node] ${msg}\n`)
  : () => {};

// ---------------------------------------------------------------------------
// Backend → pi-ai provider mapping
// ---------------------------------------------------------------------------

/**
 * Map NERF's legacy backend names to pi-ai provider names.
 * pi-ai handles all the SDK complexity internally.
 */
const BACKEND_TO_PROVIDER = {
  'claude':        'anthropic',
  'anthropic':     'anthropic',
  'openai':        'openai-responses',
  'ollama':        'openai-completions',
  'openrouter':    'openai-completions',
  'openai-compat': 'openai-completions',
  'pi-ai':         null, // uses config.pi_provider directly
  'pi':            null,
};

// ---------------------------------------------------------------------------
// Public factory
// ---------------------------------------------------------------------------

/**
 * Build a client for the configured backend.
 *
 * All backends are routed through pi-ai (pi-mono). Legacy backend names
 * (claude, openai, ollama, openrouter, openai-compat) are mapped to the
 * appropriate pi-ai provider.
 *
 * @param {import('./config-validate.js').GatewayConfig} config
 * @returns {Promise<{client: Object, model: string}>}
 */
export async function makeClient(config) {
  const backend = config.backend || 'claude';

  // Direct pi-ai/pi backend — user explicitly chose provider + model
  if (backend === 'pi-ai' || backend === 'pi') {
    debug(`client: pi-ai ${config.pi_provider}/${config.pi_model}`);
    return makePiClient({
      provider: config.pi_provider || 'anthropic',
      model: config.pi_model,
    });
  }

  // Ollama — supports both OpenAI-compatible and Anthropic-compatible APIs
  if (backend === 'ollama') {
    const api = config.ollama_api || 'openai-completions';
    const baseUrl = api === 'anthropic-messages'
      ? (config.ollama_base_url || 'http://localhost:11434').replace(/\/v1\/?$/, '')
      : (config.ollama_base_url || 'http://localhost:11434/v1');
    debug(`client: ollama at ${baseUrl}, model=${config.ollama_model}, api=${api}`);
    return makePiClient({
      provider: api,
      model: config.ollama_model,
      options: {
        baseUrl,
        apiKey: 'ollama',
      },
    });
  }

  // OpenAI direct
  if (backend === 'openai') {
    debug(`client: openai, model=${config.openai_model}`);
    return makePiClient({
      provider: 'openai-responses',
      model: config.openai_model,
      options: {
        apiKey: config.openai_api_key,
      },
    });
  }

  // OpenRouter — OpenAI-compatible API at openrouter.ai
  if (backend === 'openrouter') {
    debug(`client: openrouter, model=${config.openrouter_model}`);
    return makePiClient({
      provider: 'openai-completions',
      model: config.openrouter_model,
      options: {
        baseUrl: 'https://openrouter.ai/api/v1',
        apiKey: config.openrouter_api_key,
      },
    });
  }

  // Generic OpenAI-compatible endpoint (Groq, Together, vLLM, etc.)
  if (backend === 'openai-compat') {
    debug(`client: openai-compat at ${config.compat_base_url}, model=${config.compat_model}`);
    return makePiClient({
      provider: 'openai-completions',
      model: config.compat_model,
      options: {
        baseUrl: config.compat_base_url,
        apiKey: config.compat_api_key || 'unused',
      },
    });
  }

  // Default: Claude (Anthropic)
  debug(`client: claude, model=${config.claude_model}`);
  return makePiClient({
    provider: 'anthropic',
    model: config.claude_model,
    options: config.claude_api_key ? { apiKey: config.claude_api_key } : undefined,
  });
}

// Exported for testing / backward compatibility
export { BACKEND_TO_PROVIDER as _backendToProvider };
