/**
 * OpenCode CLI Detection
 *
 * Detects and manages OpenCode CLI installation status.
 *
 * @module utils/websearch/opencode-cli
 */

import { execSync } from 'child_process';
import type { OpenCodeCliStatus } from './types';

// Cache for OpenCode CLI status (per process)
let opencodeCliCache: OpenCodeCliStatus | null = null;

/**
 * Check if OpenCode CLI is installed globally
 *
 * OpenCode provides built-in web search via opencode/grok-code model.
 * Install: curl -fsSL https://opencode.ai/install | bash
 *
 * @returns OpenCode CLI status with path and version
 */
export function getOpenCodeCliStatus(): OpenCodeCliStatus {
  // Return cached result if available
  if (opencodeCliCache) {
    return opencodeCliCache;
  }

  const result: OpenCodeCliStatus = {
    installed: false,
    path: undefined,
    version: undefined,
  };

  try {
    const isWindows = process.platform === 'win32';
    const whichCmd = isWindows ? 'where opencode' : 'which opencode';

    const pathResult = execSync(whichCmd, {
      encoding: 'utf8',
      timeout: 5000,
      stdio: ['pipe', 'pipe', 'pipe'],
    });

    const opencodePath = pathResult.trim().split('\n')[0]; // First result on Windows

    if (opencodePath) {
      result.installed = true;
      result.path = opencodePath;

      // Try to get version
      try {
        const versionResult = execSync('opencode --version', {
          encoding: 'utf8',
          timeout: 5000,
          stdio: ['pipe', 'pipe', 'pipe'],
        });
        result.version = versionResult.trim();
      } catch {
        // Version check failed, but CLI is installed
        result.version = 'unknown';
      }
    }
  } catch {
    // Command not found - OpenCode CLI not installed
  }

  // Cache result
  opencodeCliCache = result;
  return result;
}

/**
 * Check if OpenCode CLI is available (quick boolean check)
 */
export function hasOpenCodeCli(): boolean {
  return getOpenCodeCliStatus().installed;
}

/**
 * Clear OpenCode CLI cache (for testing or after installation)
 */
export function clearOpenCodeCliCache(): void {
  opencodeCliCache = null;
}
