/**
 * Coolify connectivity checks for ops / uptime monitors.
 *
 * - HTTP API (token) — provisioning via REST
 * - SSH → Docker on host — required for shell.exec / dev containers
 */

import { listServers } from '@/lib/coolify';
import { runOnCoolifyHost } from '@/lib/coolify-ssh';

export interface CoolifyInfraHealthReport {
  checkedAt: string;
  ssh: {
    configured: boolean;
    missingEnvVars: string[];
    reachable?: boolean;
    latencyMs?: number;
    dockerDaemonOk?: boolean;
    /** docker Server.Version when daemon responds */
    dockerVersion?: string;
    error?: string;
  };
  api: {
    configured: boolean;
    reachable?: boolean;
    latencyMs?: number;
    serverCount?: number;
    error?: string;
  };
}

export function getCoolifySshConfigGap(): {
  configured: boolean;
  missingEnvVars: string[];
} {
  const missing: string[] = [];
  if (!process.env.COOLIFY_SSH_HOST?.trim()) missing.push('COOLIFY_SSH_HOST');
  if (!process.env.COOLIFY_SSH_PRIVATE_KEY_B64?.trim()) {
    missing.push('COOLIFY_SSH_PRIVATE_KEY_B64');
  }
  return { configured: missing.length === 0, missingEnvVars: missing };
}

/** True when SSH is wired and `docker` responds on the Coolify host. */
export async function runCoolifyInfraHealthProbe(): Promise<CoolifyInfraHealthReport> {
  const checkedAt = new Date().toISOString();
  const sshGap = getCoolifySshConfigGap();

  const report: CoolifyInfraHealthReport = {
    checkedAt,
    ssh: {
      configured: sshGap.configured,
      missingEnvVars: sshGap.missingEnvVars,
    },
    api: {
      configured: !!process.env.COOLIFY_API_TOKEN?.trim(),
    },
  };

  if (report.api.configured) {
    const t0 = Date.now();
    try {
      const servers = await listServers();
      report.api.reachable = true;
      report.api.latencyMs = Date.now() - t0;
      report.api.serverCount = Array.isArray(servers) ? servers.length : 0;
    } catch (e) {
      report.api.reachable = false;
      report.api.latencyMs = Date.now() - t0;
      report.api.error = e instanceof Error ? e.message : String(e);
    }
  } else {
    report.api.error = 'COOLIFY_API_TOKEN is not set';
  }

  if (!sshGap.configured) {
    report.ssh.error =
      `Missing: ${sshGap.missingEnvVars.join(', ')} — dev containers need SSH to the Docker host (see lib/coolify-ssh.ts).`;
    return report;
  }

  const tSsh = Date.now();
  try {
    const res = await runOnCoolifyHost(`docker info --format '{{.ServerVersion}}'`, {
      timeoutMs: 15_000,
      maxBytes: 8192,
    });
    report.ssh.latencyMs = Date.now() - tSsh;
    report.ssh.reachable = true;
    const ver = res.stdout.trim().split(/\s+/)[0]?.trim() ?? '';
    if (res.code === 0 && ver.length > 0) {
      report.ssh.dockerDaemonOk = true;
      report.ssh.dockerVersion = ver;
    } else {
      report.ssh.dockerDaemonOk = false;
      report.ssh.error = `docker probe exit ${res.code}: ${(res.stderr || res.stdout || '(empty)').slice(0, 600)}`;
    }
  } catch (e) {
    report.ssh.latencyMs = Date.now() - tSsh;
    report.ssh.reachable = false;
    report.ssh.dockerDaemonOk = false;
    report.ssh.error = e instanceof Error ? e.message : String(e);
  }

  return report;
}

export function isCoolifyInfraOperational(report: CoolifyInfraHealthReport): boolean {
  return (
    report.ssh.configured &&
    report.ssh.reachable === true &&
    report.ssh.dockerDaemonOk === true &&
    report.api.configured &&
    report.api.reachable === true
  );
}
