#!/usr/bin/env node
/**
 * llm-judge-config — the Layer 4 enabling-gate for router-gate v4.
 *
 * The LLM-judge engine (llm-judge.mjs) is fully built but MUST stay OFF until
 * the owner deliberately turns it on, because enabling it incurs real LLM cost
 * (~$300–1500/month per the v4.1 amendment). This module is the single switch.
 *
 * SAFE-BY-DEFAULT CONTRACT:
 *   enabled === true   ⇔   the explicit flag ROUTER_LLM_JUDGE_ENABLED is truthy
 *                          AND a key is resolvable (keychain first, then env).
 * Anything else → enabled:false. Building this file does NOT enable the judge:
 * with no flag and no key the gate is closed. keychainGet errors degrade to
 * "no key, disabled" (never throw).
 *
 * Activation (a separate, owner-driven step — NOT done here):
 *   1. store the API key in the OS keychain (or set ROUTER_LLM_KEY),
 *   2. set ROUTER_LLM_JUDGE_ENABLED=1,
 *   3. register the enforce-llm-judge-* hooks in .claude/settings.json.
 * Cost starts only after all three.
 */
import { JUDGE_MODELS } from './llm-judge.mjs';

const ENABLE_FLAG = 'ROUTER_LLM_JUDGE_ENABLED';
const KEY_ENV = 'ROUTER_LLM_KEY';
const BASE_URL_ENV = 'ROUTER_LLM_BASE_URL';
const KEYCHAIN_SERVICE = 'router-gate-llm-judge';
const KEYCHAIN_ACCOUNT = 'default';

function isTruthyFlag(v) {
  if (typeof v !== 'string') return false;
  return v.trim().toLowerCase() === '1' || v.trim().toLowerCase() === 'true';
}

/**
 * Resolve the Layer 4 judge configuration.
 *
 * @param {object} [args]
 * @param {object} [args.env]          - environment map (defaults to process.env)
 * @param {Function} [args.keychainGet] - () => string|null, OS-keychain reader (injectable for tests)
 * @returns {{enabled:boolean, apiKey:string|null, baseUrl:string|null, models:string[]}}
 */
export function resolveJudgeConfig({ env = process.env, keychainGet = defaultKeychainGet } = {}) {
  let keychainKey = null;
  try {
    const v = keychainGet();
    keychainKey = v ? String(v) : null;
  } catch {
    keychainKey = null;
  }
  const envKey = env[KEY_ENV] ? String(env[KEY_ENV]) : null;
  const apiKey = keychainKey || envKey || null;

  const flagOn = isTruthyFlag(env[ENABLE_FLAG]);
  const enabled = flagOn && apiKey !== null;

  return {
    enabled,
    apiKey,
    baseUrl: env[BASE_URL_ENV] ? String(env[BASE_URL_ENV]) : null,
    models: JUDGE_MODELS.multi,
  };
}

/**
 * Default OS-keychain reader. Lazily loads `keytar`; returns null if keytar is
 * absent or the entry is missing. Never throws (caller also guards).
 */
export function defaultKeychainGet() {
  try {
    // Lazy require keeps the native dep optional — tests inject keychainGet and
    // never hit this path; the no-op posture means missing keytar => no key.
    const require = createRequire(import.meta.url);
    const keytar = require('keytar');
    const v = keytar.getPassword ? keytar.getPasswordSync?.(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT) : null;
    return v || null;
  } catch {
    return null;
  }
}

import { createRequire } from 'node:module';

export const _internals = { ENABLE_FLAG, KEY_ENV, BASE_URL_ENV, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, isTruthyFlag };
