/**
 * Knowledge Map Utilities
 *
 * Helper functions for knowledge map operations
 */

import type { KnowledgeMap, KnowledgeMapState } from './types'
import type { Tool } from '../../tools/types'
import type { ExecutionContext } from '../../base/types'
import type { AgentMemory } from '../memory/types'
import { errorToString } from '../../../../platform/utils/error'

/**
 * Reload tools from knowledge map state (cross-turn persistence)
 *
 * Reads the knowledge-map-state from sessionMemory and rebuilds the runtime
 * knowledge map by re-loading nodes and re-discovering their child nodes.
 *
 * This reconstructs the full map structure that existed at the end of the
 * previous turn, including both explicitly loaded nodes and discovered children.
 *
 * @param knowledgeMap - The agent's knowledge map (will be mutated to add child nodes)
 * @param memory - Agent memory with sessionMemory state
 * @param context - Execution context
 * @returns Array of tools to register with the agent
 *
 * @example
 * ```typescript
 * async function initializeMemoryManager(context: ExecutionContext) {
 *   const memory = await preloadMemory(context)
 *
 *   // Reload tools from loaded knowledge nodes
 *   if (knowledgeMap) {
 *     const tools = await reloadKnowledgeMapTools(knowledgeMap, memory, context)
 *     // Tools will be registered by caller
 *   }
 *
 *   return memory
 * }
 * ```
 */
export async function reloadKnowledgeMapTools(
  knowledgeMap: KnowledgeMap,
  memory: AgentMemory,
  context: ExecutionContext
): Promise<Tool[]> {
  const stateJson = memory.sessionMemory['knowledge-map-state']
  if (!stateJson) {
    return [] // No state to reload
  }

  try {
    const state = JSON.parse(stateJson.content) as KnowledgeMapState
    const tools: Tool[] = []

    // Load each node and collect tools (BFS order - same as original load order)
    for (const nodeId of state.loadedNodes) {
      const node = knowledgeMap.nodes[nodeId]

      if (!node) {
        // Node no longer exists in knowledge map (definition changed)
        context.logger.warn(`Knowledge node '${nodeId}' not found during reload (skipping)`)
        continue
      }

      try {
        // Re-load node content from source
        const content = await node.load(context)

        // Cache prompt and set loaded flag (minimal caching)
        node.loaded = true
        node.prompt = content.prompt

        // Re-discover child nodes (rebuild runtime knowledge map)
        if (content.nodes && Object.keys(content.nodes).length > 0) {
          for (const [childId, childNode] of Object.entries(content.nodes)) {
            if (!knowledgeMap.nodes[childId]) {
              knowledgeMap.nodes[childId] = childNode
            }
          }
        }

        // Collect tools (if any)
        if (content.tools && content.tools.length > 0) {
          tools.push(...content.tools)
        }
      } catch (error) {
        // Log error but continue with other nodes
        const errorMessage = errorToString(error)
        context.logger.error(`Failed to reload knowledge node '${nodeId}': ${errorMessage}`)
      }
    }

    return tools
  } catch (error) {
    // Failed to parse state - return empty array
    const errorMessage = errorToString(error)
    context.logger.error(`Failed to parse knowledge-map-state: ${errorMessage}`)
    return []
  }
}
