import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import fs from 'fs';
import path from 'path';

/**
 * [BIZ_KER_130] 系统内存溢出预警与 HeapDump 抓取 (OOM)
 * @description 核心逻辑：监控系统内存使用情况。
 * 当内存使用率达到阈值（如 90%）时自动触发 HeapDump 并输出预警日志。
 * 联动 Sentry/SemanticLog 输出内存泄漏风险报告。
 * 遵循 Autocomplete-First (V31.5) 规范。
 */
export class MemoryWatchdogService {
  private static readonly MEMORY_THRESHOLD_PERCENT = 0.9; // 90% 触发预警
  private static readonly DUMP_INTERVAL_MS = 3600000; // 1 小时内最多执行一次 Dump
  private static lastDumpTime: number = 0;

  /**
   * 初始化内存监听
   */
  static async init() {
    this.runCheck();
    setInterval(() => this.runCheck(), 60000); // 每分钟检查一次
    logger.info(`[MemoryWatchdog] Service initialized (Threshold: ${this.MEMORY_THRESHOLD_PERCENT * 100}%)`);
  }

  /**
   * 执行内存检查
   * @private
   */
  private static async runCheck() {
    try {
      const { heapUsed, heapTotal, rss } = process.memoryUsage();
      const usagePercent = heapUsed / heapTotal;

      if (usagePercent >= this.MEMORY_THRESHOLD_PERCENT) {
        await this.handleMemoryIssue(usagePercent, heapUsed, heapTotal, rss);
      }
    } catch (err: any) {
      logger.error(`[MemoryWatchdog] Check failed: ${err.message}`);
    }
  }

  /**
   * 处理内存问题并生成报告
   * @private
   */
  private static async handleMemoryIssue(usage: number, heapUsed: number, heapTotal: number, rss: number) {
    const now = Date.now();
    let dumpPath = '';

    // 1. 生成 HeapDump (频率限制)
    if (now - this.lastDumpTime > this.DUMP_INTERVAL_MS) {
      dumpPath = await this.captureHeapDump();
      this.lastDumpTime = now;
    }

    // 2. 生成报告
    const report = `### 🚨 Memory Usage Alert: ${(usage * 100).toFixed(2)}%\n\n` +
                   `**Heap Used:** ${(heapUsed / 1024 / 1024).toFixed(2)} MB | **Heap Total:** ${(heapTotal / 1024 / 1024).toFixed(2)} MB\n` +
                   `**RSS:** ${(rss / 1024 / 1024).toFixed(2)} MB\n\n` +
                   (dumpPath ? `**HeapDump Created:** \`${dumpPath}\`\n\n` : `**Skip HeapDump:** Recently captured.\n\n`) +
                   `**Recommendation:** 系统内存占用过高，可能存在内存泄漏。请立即核查近期变更，或通过导出的 HeapDump 文件分析对象分布。`;

    await SemanticLogService.logSemantic(report, 'ERROR', 'SYSTEM_MONITOR');
    logger.error(`[MemoryWatchdog] Memory usage reached threshold: ${(usage * 100).toFixed(2)}%`);
  }

  /**
   * 捕获 HeapDump
   * @private
   */
  private static async captureHeapDump(): Promise<string> {
    try {
      // 动态加载 heapdump 库以避免强制依赖
      const heapdump = require('heapdump');
      const filename = `heapdump-${Date.now()}.heapsnapshot`;
      const fullPath = path.join(process.cwd(), 'dumps', filename);
      
      if (!fs.existsSync(path.join(process.cwd(), 'dumps'))) {
        fs.mkdirSync(path.join(process.cwd(), 'dumps'));
      }

      return new Promise((resolve, reject) => {
        heapdump.writeSnapshot(fullPath, (err: any, filename: string) => {
          if (err) reject(err);
          else resolve(filename);
        });
      });
    } catch (err) {
      return 'HEAPDUMP_LIB_MISSING';
    }
  }
}
