const logger = require('../../utils/logger')

/**
 * EnhancedResourceRegistry - 增强的资源注册表
 * 
 * 按照DPML协议架构文档设计，支持：
 * 1. 资源元数据管理（source, priority, timestamp）
 * 2. 智能合并策略（优先级和时间戳）
 * 3. 发现源优先级管理
 * 4. 批量操作支持
 */
class EnhancedResourceRegistry {
  constructor() {
    // 主索引：resourceId -> reference
    this.index = new Map()
    
    // 元数据索引：resourceId -> metadata
    this.metadata = new Map()
    
    // 发现源优先级映射
    this.sourcePriority = {
      'USER': 1,      // 最高优先级
      'PROJECT': 2,   
      'PACKAGE': 3,   
      'INTERNET': 4   // 最低优先级
    }
  }

  /**
   * 注册单个资源
   * @param {Object} resource - 资源对象
   * @param {string} resource.id - 资源ID
   * @param {string} resource.reference - 资源引用
   * @param {Object} resource.metadata - 资源元数据
   */
  register(resource) {
    this._validateResource(resource)

    const { id, reference, metadata } = resource

    // 如果资源已存在，检查是否应该覆盖
    if (this.has(id)) {
      const existingMetadata = this.metadata.get(id)
      if (!this._shouldOverride(existingMetadata, metadata)) {
        return // 不覆盖，保持现有资源
      }
    }

    // 注册资源
    this.index.set(id, reference)
    this.metadata.set(id, { ...metadata })
  }

  /**
   * 批量注册资源
   * @param {Array} resources - 资源数组
   */
  registerBatch(resources) {
    if (!Array.isArray(resources)) {
      throw new Error('Resources must be an array')
    }

    resources.forEach(resource => {
      try {
        if (resource && typeof resource === 'object') {
          this.register(resource)
        }
      } catch (error) {
        logger.warn(`[EnhancedResourceRegistry] Failed to register resource: ${error.message}`)
      }
    })
  }

  /**
   * 合并另一个注册表
   * @param {EnhancedResourceRegistry} otherRegistry - 另一个注册表实例
   */
  merge(otherRegistry) {
    if (!(otherRegistry instanceof EnhancedResourceRegistry)) {
      throw new Error('Can only merge with another EnhancedResourceRegistry instance')
    }

    // 获取所有资源并批量注册（会自动处理优先级）
    const otherResources = otherRegistry.list().map(id => ({
      id,
      reference: otherRegistry.resolve(id),
      metadata: otherRegistry.getMetadata(id)
    }))

    this.registerBatch(otherResources)
  }

  /**
   * 解析资源ID到引用
   * @param {string} resourceId - 资源ID
   * @returns {string} 资源引用
   */
  resolve(resourceId) {
    // 1. 直接查找
    if (this.index.has(resourceId)) {
      return this.index.get(resourceId)
    }

    // 2. 向后兼容：尝试添加协议前缀
    const protocols = ['role', 'thought', 'execution', 'memory']
    
    for (const protocol of protocols) {
      const fullId = `${protocol}:${resourceId}`
      if (this.index.has(fullId)) {
        return this.index.get(fullId)
      }
    }

    throw new Error(`Resource '${resourceId}' not found`)
  }

  /**
   * 检查资源是否存在
   * @param {string} resourceId - 资源ID
   * @returns {boolean} 是否存在
   */
  has(resourceId) {
    try {
      this.resolve(resourceId)
      return true
    } catch (error) {
      return false
    }
  }

  /**
   * 获取资源元数据
   * @param {string} resourceId - 资源ID
   * @returns {Object|null} 元数据对象或null
   */
  getMetadata(resourceId) {
    // 直接查找
    if (this.metadata.has(resourceId)) {
      return { ...this.metadata.get(resourceId) }
    }

    // 向后兼容查找
    const protocols = ['role', 'thought', 'execution', 'memory']
    
    for (const protocol of protocols) {
      const fullId = `${protocol}:${resourceId}`
      if (this.metadata.has(fullId)) {
        return { ...this.metadata.get(fullId) }
      }
    }

    return null
  }

  /**
   * 列出所有资源ID
   * @param {string} [protocol] - 可选的协议过滤器
   * @returns {Array<string>} 资源ID列表
   */
  list(protocol = null) {
    const allIds = Array.from(this.index.keys())
    
    if (!protocol) {
      return allIds
    }

    return allIds.filter(id => id.startsWith(`${protocol}:`))
  }

  /**
   * 获取注册表大小
   * @returns {number} 资源数量
   */
  size() {
    return this.index.size
  }

  /**
   * 清空注册表
   */
  clear() {
    this.index.clear()
    this.metadata.clear()
  }

  /**
   * 移除资源
   * @param {string} resourceId - 资源ID
   */
  remove(resourceId) {
    // 尝试直接移除
    if (this.index.has(resourceId)) {
      this.index.delete(resourceId)
      this.metadata.delete(resourceId)
      return
    }

    // 向后兼容移除
    const protocols = ['role', 'thought', 'execution', 'memory']
    
    for (const protocol of protocols) {
      const fullId = `${protocol}:${resourceId}`
      if (this.index.has(fullId)) {
        this.index.delete(fullId)
        this.metadata.delete(fullId)
        return
      }
    }
  }

  /**
   * 从发现管理器结果加载资源
   * @param {Array} discoveryResults - 发现器返回的资源数组
   */
  loadFromDiscoveryResults(discoveryResults) {
    if (!Array.isArray(discoveryResults)) {
      logger.warn('[EnhancedResourceRegistry] Discovery results must be an array')
      return
    }

    this.registerBatch(discoveryResults)
  }

  /**
   * 验证资源对象
   * @param {Object} resource - 资源对象
   * @private
   */
  _validateResource(resource) {
    if (!resource || typeof resource !== 'object') {
      throw new Error('Resource must be an object')
    }

    if (!resource.id || !resource.reference) {
      throw new Error('Resource must have id and reference')
    }

    if (!resource.metadata || typeof resource.metadata !== 'object') {
      throw new Error('Resource must have metadata with source and priority')
    }

    if (!resource.metadata.source || typeof resource.metadata.priority !== 'number') {
      throw new Error('Resource must have metadata with source and priority')
    }

    // 验证ID格式
    if (typeof resource.id !== 'string' || !resource.id.includes(':')) {
      throw new Error('Resource id must be in format "protocol:resourcePath"')
    }

    // 验证引用格式
    if (typeof resource.reference !== 'string' || !resource.reference.startsWith('@')) {
      throw new Error('Resource reference must be in DPML format "@protocol://path"')
    }
  }

  /**
   * 判断是否应该覆盖现有资源
   * @param {Object} existingMetadata - 现有资源元数据
   * @param {Object} newMetadata - 新资源元数据
   * @returns {boolean} 是否应该覆盖
   * @private
   */
  _shouldOverride(existingMetadata, newMetadata) {
    // 1. 按发现源优先级比较
    const existingSourcePriority = this.sourcePriority[existingMetadata.source] || 999
    const newSourcePriority = this.sourcePriority[newMetadata.source] || 999

    if (newSourcePriority < existingSourcePriority) {
      return true // 新资源优先级更高
    }

    if (newSourcePriority > existingSourcePriority) {
      return false // 现有资源优先级更高
    }

    // 2. 相同优先级，按数字优先级比较
    if (newMetadata.priority < existingMetadata.priority) {
      return true // 数字越小优先级越高
    }

    if (newMetadata.priority > existingMetadata.priority) {
      return false
    }

    // 3. 相同优先级，按时间戳比较（新的覆盖旧的）
    const existingTime = existingMetadata.timestamp ? new Date(existingMetadata.timestamp).getTime() : 0
    const newTime = newMetadata.timestamp ? new Date(newMetadata.timestamp).getTime() : 0

    return newTime >= existingTime
  }
}

module.exports = EnhancedResourceRegistry