/**
 * CppToolRegistrar - Registers cpp.* tools through CapabilityRegistry
 * DD §15. INV-4: registered via capability boundary, not direct runtime import.
 *
 * @module packages/toolchain-cpp/src/CppToolRegistrar
 */

import { CPP_TOOLCHAIN_CAPABILITY } from './capability.js'
import { CppProjectDetector } from './detect/CppProjectDetector.js'
import { CMakeConfigurator } from './build/CMakeConfigurator.js'
import { CppBuilder } from './build/CppBuilder.js'
import { CppTestRunner } from './test/CppTestRunner.js'
import { CppcheckRunner } from './analysis/CppcheckRunner.js'
import { ClangdClient } from './analysis/ClangdClient.js'

export class CppToolRegistrar {
  manifest = CPP_TOOLCHAIN_CAPABILITY

  /**
   * Register all cpp.* tools with the provided registry.
   * INV-4: This is called through CapabilityRegistry boundary, never via direct runtime import.
   */
  register(registry: { register(name: string, definition: any, executor: (call: any) => Promise<any>): void }, project_root: string): void {
    const detector = new CppProjectDetector(project_root)
    const configurator = new CMakeConfigurator()
    const builder = new CppBuilder()
    const tester = new CppTestRunner()
    const cppcheck = new CppcheckRunner()
    const clangd = new ClangdClient()

    // cpp.detect
    registry.register('cpp.detect', {
      name: 'cpp.detect', category: 'toolchain',
      description: 'Detect C++ project structure and toolchain',
      input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[0].input_schema,
      permissions: { read: true, write: false, network: false }, streaming: false
    }, async (call) => {
      const result = detector.detect()
      return { call_id: call.id, tool_name: 'cpp.detect', type: 'text', content: result, metadata: { timestamp: new Date().toISOString() } }
    })

    // cpp.configure
    registry.register('cpp.configure', {
      name: 'cpp.configure', category: 'toolchain',
      description: 'Configure C++ build with CMake',
      input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[1].input_schema,
      permissions: { read: true, write: true, network: false }, streaming: false
    }, async (call) => {
      const result = configurator.configure({ project_root, generator: call.arguments?.generator as any, build_type: call.arguments?.build_type as any })
      return { call_id: call.id, tool_name: 'cpp.configure', type: result.ok ? 'text' : 'error', content: result, metadata: { timestamp: new Date().toISOString() } }
    })

    // cpp.build
    registry.register('cpp.build', {
      name: 'cpp.build', category: 'toolchain',
      description: 'Build C++ project',
      input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[2].input_schema,
      permissions: { read: true, write: true, network: false }, streaming: false
    }, async (call) => {
      const result = builder.build(project_root + '/build', call.arguments?.target as string)
      return { call_id: call.id, tool_name: 'cpp.build', type: result.ok ? 'text' : 'error', content: result, metadata: { timestamp: new Date().toISOString() } }
    })

    // cpp.test
    registry.register('cpp.test', {
      name: 'cpp.test', category: 'toolchain',
      description: 'Run C++ tests',
      input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[3].input_schema,
      permissions: { read: true, write: false, network: false }, streaming: false
    }, async (call) => {
      const result = tester.run_tests(project_root + '/build')
      return { call_id: call.id, tool_name: 'cpp.test', type: result.ok ? 'text' : 'error', content: result, metadata: { timestamp: new Date().toISOString() } }
    })

    // cpp.cppcheck
    registry.register('cpp.cppcheck', {
      name: 'cpp.cppcheck', category: 'toolchain',
      description: 'Run cppcheck static analysis',
      input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[4].input_schema,
      permissions: { read: true, write: false, network: false }, streaming: false
    }, async (call) => {
      const result = cppcheck.run(project_root, { enable_all: call.arguments?.enable_all as boolean, check_config: call.arguments?.check_config as boolean })
      return { call_id: call.id, tool_name: 'cpp.cppcheck', type: result.ok ? 'text' : 'error', content: result, metadata: { timestamp: new Date().toISOString() } }
    })

    // cpp.clangd
    registry.register('cpp.clangd', {
      name: 'cpp.clangd', category: 'toolchain',
      description: 'Query clangd for symbol info',
      input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[5].input_schema,
      permissions: { read: true, write: false, network: false }, streaming: false
    }, async (call) => {
      const result = await clangd.query_symbol(call.arguments?.file as string, call.arguments?.line as number, call.arguments?.column as number)
      return { call_id: call.id, tool_name: 'cpp.clangd', type: 'text', content: result, metadata: { timestamp: new Date().toISOString() } }
    })
  }
}
