/**
 * Tool Registration - registers all tools with the ToolRegistry
 *
 * Tool categories:
 *   Core (mirrors Claude Code): Read, Edit, Write, Bash, Grep, Glob, TodoWrite, SubAgent
 *   VL Intelligence (surpasses Claude Code): VLSymbols, VLImpact, VLEditSection, VLAutoFix
 *   VL Standard: VLValidate, VLMetadata
 *   Workflow: WorkflowRun, WorkspaceAPI
 */
import { createReadFileTool } from './read-file.js';
import { createEditFileTool } from './edit-file.js';
import { createWriteFileTool } from './write-file.js';
import { createBashTool } from './bash.js';
import { createGrepTool } from './grep.js';
import { createGlobTool } from './glob.js';
import { createTodoWriteTool } from './todo-write.js';
import { createSubAgentTool } from './sub-agent.js';
import { createVLValidateTool } from './vl-validate.js';
import { createVLMetadataTool } from './vl-metadata.js';
import { createVLSymbolsTool } from './vl-symbols.js';
import { createVLImpactTool } from './vl-impact.js';
import { createVLEditSectionTool } from './vl-edit-section.js';
import { createVLAutoFixTool } from './vl-autofix.js';
import { createWorkflowRunTool } from './workflow-run.js';
import { createWorkspaceAPITool } from './workspace-api.js';
import { createVLParseTool } from './vl-parse.js';
import { createAskUserTool } from './ask-user.js';
import { createMemoryTool } from './memory.js';
import { createToolSearchTool } from './tool-search.js';
import { createDocCenterTool } from './doc-center.js';
import { createBrowserInspectTool } from './browser-inspect.js';
import { createVLComponentTestTool } from './vl-component-test.js';
import { createVLSyntaxRefTool } from './vl-syntax-ref.js';
import { createVLCompileTool } from './vl-compile.js';
import { createMetaDiffTool } from './meta-diff.js';
import { createSectionDiffTool } from './section-diff.js';
import { createVLCascadeEditTool } from './vl-cascade-edit.js';
import { createVLMetaTestTool } from './vl-meta-test.js';
import { createAutoTestPipelineTool } from './autotest-pipeline.js';
import { createComponentFetchTool } from './component-fetch.js';
import { createVLLintTool } from './vl-lint.js';
import { createVLGenerateTool } from './vl-generate.js';
import { createVLAdjustTool } from './vl-adjust.js';
import { createWorkspaceManagerTool } from './workspace-manager.js';
import { createSelfModifyTool, VL_CODE_INSTALL_DIR } from './self-modify.js';
import fsSync from 'fs';
import pathMod from 'path';
import osMod from 'os';

/**
 * @param {Object} registry - Tool registry
 * @param {Object} config - VL-Code configuration
 * @param {Object} projectContext - VL project context
 * @param {Object} [engines] - Local engine instances
 * @param {import('../engine/local-workspace.js').LocalWorkspace} [engines.localWorkspace]
 */
export function registerAllTools(registry, config, projectContext, { localWorkspace } = {}) {
  const isVL = projectContext.isVLProject();

  // Core file tools (mirrors Claude Code) — always registered
  registry.register('ReadFile', createReadFileTool(config));
  registry.register('EditFile', createEditFileTool(config));
  registry.register('WriteFile', createWriteFileTool(config));

  // System tools — always registered
  registry.register('Bash', createBashTool(config));
  registry.register('Grep', createGrepTool(config));
  registry.register('Glob', createGlobTool(config));

  // State management — always registered
  registry.register('TodoWrite', createTodoWriteTool());

  // Sub-agent — always registered
  registry.register('SubAgent', createSubAgentTool());

  // Interactive tools — always registered
  registry.register('AskUserQuestion', createAskUserTool());
  registry.register('Memory', createMemoryTool(config));

  // Tool Search / Deferred Loading — always registered
  registry.register('ToolSearch', createToolSearchTool(registry));

  // Workflow & Deploy tools — always registered (useful for non-VL too)
  registry.register('WorkflowRun', createWorkflowRunTool(config));
  registry.register('WorkspaceAPI', createWorkspaceAPITool(config, localWorkspace));

  // Cloud document management — always registered
  registry.register('DocCenter', createDocCenterTool(config));

  // Component library — search, fetch, adapt components from DocCenter + web
  registry.register('ComponentFetch', createComponentFetchTool(config));

  // Workspace management — create, switch, list workspaces from AI conversation
  registry.register('WorkspaceManager', createWorkspaceManagerTool(config));

  // Browser automation — always registered
  registry.register('BrowserInspect', createBrowserInspectTool(config));

  // VL Generation — one-call codegen workflow trigger
  registry.register('VLGenerate', createVLGenerateTool(config));

  // VL Adjustment — modify existing projects (add page, add service, theme, general)
  registry.register('VLAdjust', createVLAdjustTool(config));

  // VL compile, test & reference tools — always registered (they call HTTP APIs or handle non-VL gracefully)
  registry.register('VLCompile', createVLCompileTool(config));
  registry.register('VLLint', createVLLintTool(config));
  registry.register('VLParse', createVLParseTool(config));
  registry.register('VLSyntaxRef', createVLSyntaxRefTool(config));
  registry.register('VLComponentTest', createVLComponentTestTool(config));
  registry.register('AutoTestPipeline', createAutoTestPipelineTool(config, projectContext));

  // VL-specific tools — only for VL projects (tightly coupled to projectContext)
  if (isVL) {
    registry.register('VLValidate', createVLValidateTool(projectContext));
    registry.register('VLMetadata', createVLMetadataTool(projectContext));
  }

  // Self-modification — always registered (AI can improve itself)
  registry.register('SelfModify', createSelfModifyTool(config));

  // --- VL Intelligence tools (registered later when modules are ready) ---
  // These are registered by registerIntelligenceTools() after index.js
  // initializes SymbolIndex, ImpactAnalyzer, AutoFix
}

/**
 * Register VL intelligence tools (requires initialized modules)
 * Called from index.js after SymbolIndex, ImpactAnalyzer, AutoFix are ready
 */
export function registerIntelligenceTools(registry, config, { symbolIndex, impactAnalyzer, autoFix, projectContext }) {
  // Skip VL intelligence tools for non-VL projects
  if (projectContext && !projectContext.isVLProject()) return;

  // VL Language Intelligence (surpasses Claude Code)
  registry.register('VLSymbols', createVLSymbolsTool(symbolIndex));
  registry.register('VLImpact', createVLImpactTool(impactAnalyzer));
  registry.register('VLEditSection', createVLEditSectionTool(config));
  registry.register('VLAutoFix', createVLAutoFixTool(autoFix));

  // Meta-Diff: deterministic ProjectMeta diff (needs symbolIndex for cascade impact)
  registry.register('MetaDiff', createMetaDiffTool(config, symbolIndex));

  // Section-Diff: section-level diff & merge for VL files
  registry.register('SectionDiff', createSectionDiffTool(config));

  // Cascade Edit: auto-fix all callers after interface changes
  registry.register('VLCascadeEdit', createVLCascadeEditTool(config, impactAnalyzer, registry));

  // Meta-Driven Test Skeleton: generate test cases from ProjectMeta (no LLM)
  registry.register('VLMetaTest', createVLMetaTestTool(config));
}

/**
 * Load user-defined tools from ~/.vl-code/tools/
 * These are tools written by the AI (via SelfModify) or the developer.
 * Loaded dynamically — no restart needed after write_source + register_tool.
 * Called after registerAllTools() and registerIntelligenceTools().
 */
export async function loadUserTools(registry, config) {
  const userToolsDir = pathMod.join(osMod.homedir(), '.vl-code', 'tools');
  const registryFile = pathMod.join(userToolsDir, '_registry.json');

  if (!fsSync.existsSync(registryFile)) return;

  let entries = [];
  try {
    entries = JSON.parse(fsSync.readFileSync(registryFile, 'utf-8'));
  } catch {
    return;
  }

  for (const entry of entries) {
    const { tool_name, tool_file, factory_fn, factory_args } = entry;
    if (!tool_name || !tool_file || !factory_fn) continue;
    if (registry.has?.(tool_name)) continue; // already registered

    try {
      const mod = await import(tool_file);
      const factory = mod[factory_fn];
      if (typeof factory !== 'function') {
        console.warn(`[UserTools] ${tool_name}: factory ${factory_fn} not found in ${tool_file}`);
        continue;
      }
      // Build args: simple eval of "config" or "config, projectContext" etc.
      const argValue = (factory_args || 'config') === 'config' ? config : config;
      registry.register(tool_name, factory(argValue));
      console.log(`[UserTools] Loaded: ${tool_name} from ${tool_file}`);
    } catch (e) {
      console.warn(`[UserTools] Failed to load ${tool_name}: ${e.message}`);
    }
  }
}
