#!/usr/bin/env node

const DEFAULT_URL = 'http://127.0.0.1/api/v1/health/version';

const url = process.argv[2] || process.env.RUNTIME_VERSION_URL || DEFAULT_URL;
const expectedVersion = process.argv[3] || process.env.APP_VERSION || process.env.GITHUB_SHA || '';
const attempts = Number.parseInt(process.env.RUNTIME_VERSION_ATTEMPTS || '30', 10);
const intervalMs = Number.parseInt(process.env.RUNTIME_VERSION_INTERVAL_MS || '2000', 10);
const timeoutMs = Number.parseInt(process.env.RUNTIME_VERSION_TIMEOUT_MS || '5000', 10);

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

function isVersionPayload(value) {
  return (
    value &&
    typeof value === 'object' &&
    value.service === 'server' &&
    typeof value.version === 'string'
  );
}

async function fetchVersion() {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const response = await fetch(url, { signal: controller.signal });
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    const payload = await response.json();
    if (!isVersionPayload(payload)) {
      throw new Error(`Unexpected payload: ${JSON.stringify(payload)}`);
    }

    return payload;
  } finally {
    clearTimeout(timeout);
  }
}

let lastError = null;

for (let attempt = 1; attempt <= attempts; attempt += 1) {
  try {
    const payload = await fetchVersion();
    if (expectedVersion && payload.version !== expectedVersion) {
      throw new Error(`Expected ${expectedVersion}, got ${payload.version}`);
    }

    console.log(`Runtime version verified: ${payload.version}`);
    process.exit(0);
  } catch (error) {
    lastError = error;
    if (attempt < attempts) {
      await sleep(intervalMs);
    }
  }
}

console.error(`Runtime version check failed for ${url}: ${lastError?.message || 'unknown error'}`);
process.exit(1);
