import os from "node:os";
import si from "systeminformation";

export type HardwareTier = "gpu" | "apple_silicon" | "cpu_only";

export interface HardwareResult {
  tier: HardwareTier;
  totalGb: number;
  gpuName?: string;
  gpuVramGb?: number;
}

/**
 * Detect the hardware tier of the current machine.
 *
 * Priority:
 * 1. Apple Silicon (darwin + CPU model starts with "Apple")
 * 2. GPU with >= 4 GB VRAM (detected via systeminformation with 3s timeout)
 * 3. CPU-only fallback
 *
 * @param platform - Override process.platform for testing
 */
export async function detectHardware(platform?: string): Promise<HardwareResult> {
  const resolvedPlatform = platform ?? process.platform;
  const totalGb = Math.round((os.totalmem() / (1024 * 1024 * 1024)) * 10) / 10;

  // Apple Silicon path
  if (resolvedPlatform === "darwin") {
    const cpus = os.cpus();
    if (cpus.length > 0 && cpus[0]?.model?.startsWith("Apple")) {
      return { tier: "apple_silicon", totalGb };
    }
  }

  // GPU detection with 3-second timeout
  try {
    const timeoutPromise = new Promise<never>((_, reject) =>
      setTimeout(() => reject(new Error("GPU detection timeout")), 3000)
    );
    const graphicsPromise = si.graphics();
    const graphics = await Promise.race([graphicsPromise, timeoutPromise]);

    const controller = graphics.controllers?.[0];
    const vram = controller?.vram ?? 0;
    if (controller && vram >= 4096) {
      return {
        tier: "gpu",
        totalGb,
        gpuName: controller.model,
        gpuVramGb: Math.round(vram / 1024),
      };
    }
  } catch {
    // Timeout or error — fall through to cpu_only
  }

  return { tier: "cpu_only", totalGb };
}
