// Minimal test runner implementation to run tests without requiring vitest.
const fs = require("fs");
const path = require("path");
const Module = require("module");

const testFailures: string[] = [];
const suiteStack: string[] = [];
let testCount = 0;

function formatTitle(title: string, value: string) {
  if (title.includes("%s")) {
    return title.replace("%s", value);
  }
  return `${title} ${value}`;
}

function fullTestName(name: string) {
  return [...suiteStack, name].join(" > ");
}

global.describe = function describe(name: string, fn: () => void) {
  suiteStack.push(name);
  try {
    fn();
  } finally {
    suiteStack.pop();
  }
};

global.describe.each = (values: string[]) => {
  return (name: string, fn: (value: string) => void) => {
    values.forEach((value) => {
      global.describe(formatTitle(name, value), () => fn(value));
    });
  };
};

global.it = function it(name: string, fn: () => void) {
  const fullName = fullTestName(name);
  testCount += 1;
  try {
    fn();
    console.log(`ok ${testCount} - ${fullName}`);
  } catch (error) {
    testFailures.push(fullName);
    console.log(`not ok ${testCount} - ${fullName}`);
    console.error(error);
  }
};

global.expect = function expect(actual: unknown) {
  return {
    toBe(expected: unknown) {
      if (!Object.is(actual, expected)) {
        throw new Error(
          `Expected ${JSON.stringify(actual)} to be ${JSON.stringify(expected)}`
        );
      }
    },
  };
};

process.on("exit", () => {
  console.log(`1..${testCount}`);
  if (testFailures.length > 0) {
    console.error(`${testFailures.length} test(s) failed`);
    process.exitCode = 1;
  }
});

const originalResolveFilename = Module._resolveFilename;
Module._resolveFilename = function resolveFilename(
  request: string,
  parent: { filename?: string } | null,
  isMain: boolean,
  options: unknown
) {
  try {
    return originalResolveFilename.call(this, request, parent, isMain, options);
  } catch (error: unknown) {
    if (error && (error as { code?: string }).code === "MODULE_NOT_FOUND") {
      const baseDir = parent && parent.filename ? path.dirname(parent.filename) : process.cwd();
      const candidate = path.resolve(baseDir, request);
      const tryPaths = [`${candidate}.ts`, path.join(candidate, "index.ts")];
      for (const tryPath of tryPaths) {
        if (fs.existsSync(tryPath)) {
          return tryPath;
        }
      }
    }
    throw error;
  }
};

require(path.resolve("src/__tests__/index.test.ts"));
