// {{ display_name }} MCP server — generated by mcpify. Do not hand-edit.

import type { ComponentRegistry } from './component-registry.js';
import { logger } from './logger.js';

export type HealthCheckFn = () => Promise<void>;

interface RegisteredCheck {
  name: string;
  check: HealthCheckFn;
}

const DEFAULT_INTERVAL_MS = 30_000;
const DEFAULT_TIMEOUT_MS = 5_000;

/**
 * Runs registered health checks periodically, updating a shared
 * `ComponentRegistry` so degraded-mode startup and a `/healthz`-style check
 * (plus the `test-connection` CLI command) can report accurately — REQ-2.3.4.
 */
export class HealthCheckManager {
  private readonly checks: RegisteredCheck[] = [];
  private timer?: NodeJS.Timeout;

  constructor(
    private readonly registry: ComponentRegistry,
    private readonly intervalMs = DEFAULT_INTERVAL_MS,
    private readonly timeoutMs = DEFAULT_TIMEOUT_MS,
  ) {}

  register(name: string, check: HealthCheckFn, critical = true): void {
    this.registry.register(name, critical);
    this.checks.push({ name, check });
  }

  async runOnce(): Promise<void> {
    await Promise.all(
      this.checks.map(async ({ name, check }) => {
        try {
          await Promise.race([
            check(),
            new Promise<never>((_, reject) => setTimeout(() => reject(new Error('timed out')), this.timeoutMs)),
          ]);
          this.registry.report(name, 'healthy');
        } catch (error) {
          const message = error instanceof Error ? error.message : String(error);
          logger.warn({ component: name, err: message }, 'health check failed');
          this.registry.report(name, 'unhealthy', message);
        }
      }),
    );
  }

  start(): void {
    this.timer = setInterval(() => void this.runOnce(), this.intervalMs);
    this.timer.unref?.();
  }

  stop(): void {
    if (this.timer) clearInterval(this.timer);
  }
}
