#!/usr/bin/env node

const BASE_URL = resolveBaseUrl();
const token = process.env.CAMPAIGN_RETRY_JOB_TOKEN?.trim();
const healthToken = process.env.HEALTHCHECK_TOKEN?.trim();

if (!BASE_URL) {
  console.error("Missing APP_URL / NEXT_PUBLIC_APP_URL / OPS_BASE_URL");
  process.exit(1);
}

function resolveBaseUrl() {
  return [
    process.env.OPS_BASE_URL,
    process.env.APP_URL,
    process.env.NEXT_PUBLIC_APP_URL
  ].map((value) => value?.trim()).find(Boolean);
}

function buildUrl(path) {
  return `${BASE_URL.replace(/\/+$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
}

async function requestJson(url, options = {}) {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 12_000);

  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        accept: "application/json",
        ...options.headers
      },
      signal: controller.signal
    });

    const text = await response.text();
    clearTimeout(timeout);

    let parsed = null;
    try {
      parsed = text ? JSON.parse(text) : null;
    } catch {
      parsed = text;
    }

    return {
      status: response.status,
      ok: response.ok,
      data: parsed,
      raw: response.ok ? null : text
    };
  } catch (error) {
    clearTimeout(timeout);
    return {
      status: 0,
      ok: false,
      data: null,
      raw: error instanceof Error ? error.message : String(error)
    };
  }
}

function appendToken(url, tokenValue) {
  if (!tokenValue) {
    return url;
  }

  const parsed = new URL(url);
  if (!parsed.searchParams.get("token")) {
    parsed.searchParams.set("token", tokenValue);
  }
  return parsed.toString();
}

function passFail(ok) {
  return ok ? "PASS" : "FAIL";
}

const results = [];
const checks = [
  {
    name: "Application root",
    url: buildUrl("/"),
    headers: {}
  },
  {
    name: "Health endpoint",
    url: buildUrl("/api/health"),
    headers: healthToken
      ? {
          Authorization: `Bearer ${healthToken}`
        }
      : {}
  },
  {
    name: "Campaign retry job state",
    url: appendToken(buildUrl("/api/jobs/campaign-retry"), token),
    headers: token
      ? {
          Authorization: `Bearer ${token}`
        }
      : {}
  }
];

for (const check of checks) {
  const result = await requestJson(check.url, { headers: check.headers });
  results.push({ ...check, result });
  console.log(`[${passFail(result.ok)}] ${check.name}: ${result.status}`);
}

const failedChecks = results.filter((item) => !item.result.ok);
if (failedChecks.length > 0) {
  console.error("Some health checks failed");
  for (const item of failedChecks) {
    console.error(`- ${item.name}: ${item.result.raw || JSON.stringify(item.result.data)}`);
  }
  process.exit(1);
}

console.log("All checks passed.");
