/**
 * ContextManager - 上下文管理器
 *
 * 职责：
 * 1. 统一管理所有 Context 的生命周期
 * 2. 提供上下文查询接口
 * 3. 处理上下文清理和资源释放
 */

const { RequestContext } = require('./request-context');
const { SessionContext } = require('./session-context');
const { AgentContext } = require('./agent-context');

class ContextManager {
  /**
   * @param {Framework} framework - 框架实例
   */
  constructor(framework) {
    this.framework = framework;

    // Context 存储
    this._requestContexts = new Map(); // requestId → RequestContext
    this._sessionContexts = new Map(); // sessionId → SessionContext
    this._agentContexts = new Map(); // agentId → AgentContext

    // 引用计数（用于自动清理）
    this._refCounts = new Map();

    // 事件转发
    this._setupEventForwarding();
  }

  /**
   * 设置事件转发
   * @private
   */
  _setupEventForwarding() {
    if (this.framework) {
      this.framework.on('session:context-created', (ctx) => {
        // 可以在这里添加日志、监控等
      });
      this.framework.on('session:context-destroyed', (ctx) => {
        // 可以在这里添加清理逻辑
      });
    }
  }

  // ==================== Request Context ====================

  /**
   * 创建 Request Context
   * @param {Object} options - 请求选项
   * @returns {RequestContext}
   */
  createRequestContext(options = {}) {
    const ctx = new RequestContext(options);
    this._requestContexts.set(ctx.requestId, ctx);
    this._refCounts.set(`request:${ctx.requestId}`, 1);
    return ctx;
  }

  /**
   * 获取 Request Context
   * @param {string} requestId - 请求 ID
   * @returns {RequestContext|null}
   */
  getRequestContext(requestId) {
    return this._requestContexts.get(requestId) || null;
  }

  /**
   * 释放 Request Context
   * @param {string} requestId - 请求 ID
   */
  releaseRequestContext(requestId) {
    const ctx = this._requestContexts.get(requestId);
    if (ctx) {
      ctx.cancel();
      this._requestContexts.delete(requestId);
      this._refCounts.delete(`request:${requestId}`);
    }
  }

  /**
   * 增加 Request Context 引用计数
   * @param {string} requestId - 请求 ID
   */
  retainRequestContext(requestId) {
    const key = `request:${requestId}`;
    this._refCounts.set(key, (this._refCounts.get(key) || 0) + 1);
  }

  // ==================== Session Context ====================

  /**
   * 获取或创建 Session Context
   * @param {string} sessionId - 会话 ID
   * @param {Object} options - 配置选项
   * @returns {SessionContext}
   */
  getOrCreateSessionContext(sessionId, options = {}) {
    let ctx = this._sessionContexts.get(sessionId);
    if (!ctx) {
      ctx = new SessionContext(sessionId, this.framework, options);
      this._sessionContexts.set(sessionId, ctx);
      this._refCounts.set(`session:${sessionId}`, 1);
    } else {
      // 增加引用计数
      const key = `session:${sessionId}`;
      this._refCounts.set(key, (this._refCounts.get(key) || 0) + 1);
    }
    return ctx;
  }

  /**
   * 获取 Session Context
   * @param {string} sessionId - 会话 ID
   * @returns {SessionContext|null}
   */
  getSessionContext(sessionId) {
    return this._sessionContexts.get(sessionId) || null;
  }

  /**
   * 释放 Session Context（减少引用计数）
   * @param {string} sessionId - 会话 ID
   * @param {boolean} [force=false] - 强制销毁
   */
  releaseSessionContext(sessionId, force = false) {
    const key = `session:${sessionId}`;
    const count = this._refCounts.get(key) || 0;

    if (force || count <= 1) {
      const ctx = this._sessionContexts.get(sessionId);
      if (ctx) {
        ctx.destroy();
        this.framework.emit('session:context-destroyed', ctx);
      }
      this._sessionContexts.delete(sessionId);
      this._refCounts.delete(key);
    } else {
      this._refCounts.set(key, count - 1);
    }
  }

  /**
   * 增加 Session Context 引用计数
   * @param {string} sessionId - 会话 ID
   */
  retainSessionContext(sessionId) {
    const key = `session:${sessionId}`;
    this._refCounts.set(key, (this._refCounts.get(key) || 0) + 1);
  }

  /**
   * 检查 Session Context 是否存在
   * @param {string} sessionId - 会话 ID
   * @returns {boolean}
   */
  hasSessionContext(sessionId) {
    return this._sessionContexts.has(sessionId);
  }

  // ==================== Agent Context ====================

  /**
   * 获取或创建 Agent Context
   * @param {string} agentId - Agent ID
   * @param {Agent} agent - Agent 实例
   * @param {Object} options - 配置选项
   * @returns {AgentContext}
   */
  getOrCreateAgentContext(agentId, agent, options = {}) {
    let ctx = this._agentContexts.get(agentId);
    if (!ctx) {
      ctx = new AgentContext(agentId, agent, options);
      this._agentContexts.set(agentId, ctx);
    }
    return ctx;
  }

  /**
   * 获取 Agent Context
   * @param {string} agentId - Agent ID
   * @returns {AgentContext|null}
   */
  getAgentContext(agentId) {
    return this._agentContexts.get(agentId) || null;
  }

  /**
   * 删除 Agent Context
   * @param {string} agentId - Agent ID
   */
  removeAgentContext(agentId) {
    const ctx = this._agentContexts.get(agentId);
    if (ctx) {
      ctx.destroy();
      this._agentContexts.delete(agentId);
    }
  }

  // ==================== 批量操作 ====================

  /**
   * 销毁所有 Session Context
   */
  destroyAllSessionContexts() {
    for (const [sessionId] of this._sessionContexts) {
      this.releaseSessionContext(sessionId, true);
    }
  }

  /**
   * 清理过期的 Request Context
   * @param {number} [maxAge=300000] - 最大存活时间（毫秒），默认 5 分钟
   */
  cleanupExpiredRequests(maxAge = 300000) {
    const now = Date.now();
    for (const [requestId, ctx] of this._requestContexts) {
      if (now - ctx.startTime > maxAge) {
        this.releaseRequestContext(requestId);
      }
    }
  }

  /**
   * 清理所有 Context
   */
  destroyAll() {
    // 清理 Request Contexts
    for (const [requestId] of this._requestContexts) {
      this.releaseRequestContext(requestId);
    }

    // 清理 Session Contexts
    this.destroyAllSessionContexts();

    // 清理 Agent Contexts
    for (const [agentId] of this._agentContexts) {
      this.removeAgentContext(agentId);
    }
  }

  // ==================== 统计 ====================

  /**
   * 获取统计信息
   * @returns {Object}
   */
  getStats() {
    return {
      activeRequests: this._requestContexts.size,
      activeSessions: this._sessionContexts.size,
      activeAgents: this._agentContexts.size,
      refCounts: Object.fromEntries(this._refCounts),
    };
  }

  /**
   * 获取内存使用估计
   * @returns {Object}
   */
  getMemoryUsage() {
    let sessionMessagesSize = 0;
    let sessionVariablesSize = 0;

    for (const ctx of this._sessionContexts.values()) {
      sessionMessagesSize += ctx.messageStore.messages.length;
      sessionVariablesSize += ctx.variables.size;
    }

    return {
      requestContexts: this._requestContexts.size,
      sessionContexts: this._sessionContexts.size,
      agentContexts: this._agentContexts.size,
      totalSessionMessages: sessionMessagesSize,
      totalSessionVariables: sessionVariablesSize,
    };
  }
}

module.exports = { ContextManager };
