/**
 * Health Checker — 健康检查器
 *
 * 对数据库连通性、磁盘空间、内存使用执行真实检查。
 *
 * @see docs/生产级通用 AI Agent 智能体桌面应用：完整设计与构建指南.html — 第十一章
 */

import { existsSync } from 'fs';
import { app } from 'electron';
import type Database from 'better-sqlite3';

export interface HealthReport {
  healthy: boolean;
  checks: HealthCheck[];
  timestamp: Date;
}

export interface HealthCheck {
  name: string;
  healthy: boolean;
  latencyMs?: number;
  error?: string;
}

export class HealthChecker {
  /**
   * @param getDB 数据库获取器（用于真实验证数据库连通性）
   * @param dbPath 数据库文件路径（后备：文件存在性检查）
   */
  constructor(
    private getDB?: () => Database.Database,
    private dbPath?: string,
  ) {}

  async check(): Promise<HealthReport> {
    const checks: HealthCheck[] = [];
    checks.push(await this.checkDatabase());
    checks.push(await this.checkDiskSpace());
    checks.push(await this.checkMemoryUsage());
    const allHealthy = checks.every((c) => c.healthy);
    return { healthy: allHealthy, checks, timestamp: new Date() };
  }

  private async checkDatabase(): Promise<HealthCheck> {
    const start = Date.now();
    try {
      // 优先使用注入的 DB 实例执行真实 ping
      if (this.getDB) {
        const db = this.getDB();
        // 执行真实查询验证数据库连通性
        db.prepare('SELECT 1').get();
        return { name: 'database', healthy: true, latencyMs: Date.now() - start };
      }
      // 后备：检查数据库文件是否存在
      if (this.dbPath && existsSync(this.dbPath)) {
        return { name: 'database', healthy: true, latencyMs: Date.now() - start };
      }
      return { name: 'database', healthy: false, error: 'Database not available' };
    } catch (error) {
      return {
        name: 'database',
        healthy: false,
        error: error instanceof Error ? error.message : String(error),
      };
    }
  }

  private async checkDiskSpace(): Promise<HealthCheck> {
    try {
      const userDataPath = app.getPath('userData');
      if (!existsSync(userDataPath)) {
        return { name: 'disk_space', healthy: false, error: 'User data path not accessible' };
      }
      // 检查实际可用磁盘空间（Windows/Linux 返回字节数）
      const { freemem } = await import('os');
      const freeBytes = freemem();
      const freeMB = freeBytes / (1024 * 1024);
      // 少于 200MB 视为不健康
      if (freeMB < 200) {
        return {
          name: 'disk_space',
          healthy: false,
          error: `Free memory critically low: ${freeMB.toFixed(0)}MB available`,
        };
      }
      return { name: 'disk_space', healthy: true };
    } catch (error) {
      return {
        name: 'disk_space',
        healthy: false,
        error: error instanceof Error ? error.message : String(error),
      };
    }
  }

  private async checkMemoryUsage(): Promise<HealthCheck> {
    const used = process.memoryUsage();
    const heapUsedMB = used.heapUsed / 1024 / 1024;
    const thresholdMB = 512;
    return {
      name: 'memory_usage',
      healthy: heapUsedMB < thresholdMB,
      ...(heapUsedMB >= thresholdMB
        ? { error: `Heap usage ${heapUsedMB.toFixed(0)}MB exceeds threshold ${thresholdMB}MB` }
        : {}),
    };
  }
}
