#!/usr/bin/env node
'use strict';
/**
 * Shared test harness for SkyCloud engine suites.
 * Usage: const { load, ok, throws, suite } = require('../helpers/harness');
 */
const assert = require('node:assert');
const path = require('node:path');

process.env.SC_TEST = process.env.SC_TEST || '1';
process.env.SC_TEST_NO_LIVE = process.env.SC_TEST_NO_LIVE || '1';

let _engine = null;
function load() {
  if (!_engine) {
    const dump = path.join(__dirname, 'engine-dump.js');
    _engine = require(dump).__test;
    try {
      _engine.ensureId();
      _engine.deriveKeys();
    } catch { /* ignore */ }
  }
  return _engine;
}

let pass = 0;
let fail = 0;

function ok(name, cond) {
  assert.ok(cond, name);
  pass++;
  console.log('PASS ' + name);
}

function eq(name, actual, expected) {
  assert.strictEqual(actual, expected, name);
  pass++;
  console.log('PASS ' + name);
}

function throws(name, fn, msgPart) {
  let threw = false;
  let errMsg = '';
  try { fn(); } catch (e) { threw = true; errMsg = e?.message || String(e); }
  assert.ok(threw, name + ' (expected throw)');
  if (msgPart) assert.ok(errMsg.includes(msgPart), name + ' msg includes ' + msgPart);
  pass++;
  console.log('PASS ' + name);
}

function deepEq(name, actual, expected) {
  assert.deepStrictEqual(actual, expected, name);
  pass++;
  console.log('PASS ' + name);
}

function summary(label) {
  console.log('\nALL ' + pass + ' ' + label + ' PASSED');
  return pass;
}

function failSuite(name, err) {
  fail++;
  console.error('FAIL SUITE ' + name + ':', err.message);
  if (process.env.SC_TEST_VERBOSE) console.error(err.stack);
  process.exit(1);
}

function suite(name, fn) {
  try {
    fn({ load, ok, eq, throws, deepEq, assert });
    return true;
  } catch (e) {
    failSuite(name, e);
    return false;
  }
}

module.exports = { load, ok, eq, throws, deepEq, summary, suite, assert, passCount: () => pass };
