import console from "node:console";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { validateAndHashStage } from "./lib/package-integrity.ts";

const root = mkdtempSync(join(tmpdir(), "wrnexus-stage-integrity-"));
const manifest = {
  name: "@wrnexus/probe",
  version: "0.8.0",
  description: "Integrity probe.",
  license: "MIT",
  main: "./dist/index.js",
  module: "./dist/index.js",
  types: "./dist/index.d.ts",
  exports: { ".": { import: "./dist/index.js", types: "./dist/index.d.ts" } },
  files: ["dist", "README.md"],
  repository: { type: "git", url: "https://example.test/repository.git" },
  homepage: "https://example.test",
  bugs: { url: "https://example.test/issues" },
  keywords: ["probe"],
  engines: { bun: ">=1.3.0" },
  publishConfig: { registry: "https://registry.npmjs.org/", access: "restricted" },
};
try {
  const safe = join(root, "safe");
  mkdirSync(join(safe, "dist"), { recursive: true });
  writeFileSync(join(safe, "dist", "index.js"), "export const safe = true;\n");
  writeFileSync(join(safe, "dist", "index.d.ts"), "export declare const safe: true;\n");
  const result = validateAndHashStage(safe, manifest);
  if (result.files.length !== 2 || result.files.some((file) => file.sha256.length !== 64)) {
    throw new Error("Safe stage did not produce deterministic SHA-256 records.");
  }

  const forbidden = join(root, "forbidden");
  mkdirSync(forbidden);
  writeFileSync(join(forbidden, ".env"), "TOKEN=secret\n");
  let rejected = false;
  try {
    validateAndHashStage(forbidden, manifest);
  } catch {
    rejected = true;
  }
  if (!rejected) throw new Error("Secret-like stage file was not rejected.");

  const temporaryShim = join(root, "temporary-shim");
  mkdirSync(temporaryShim);
  writeFileSync(join(temporaryShim, "focus-shims.d.ts"), "declare const Bun: any;\n");
  rejected = false;
  try {
    validateAndHashStage(temporaryShim, manifest);
  } catch {
    rejected = true;
  }
  if (!rejected) throw new Error("Temporary typecheck shim was not rejected.");

  const sourceMap = join(root, "source-map");
  mkdirSync(sourceMap);
  writeFileSync(join(sourceMap, "index.js.map"), "{}\n");
  rejected = false;
  try {
    validateAndHashStage(sourceMap, manifest);
  } catch {
    rejected = true;
  }
  if (!rejected) throw new Error("Source map was not rejected.");

  const leaked = join(root, "leaked-secret");
  mkdirSync(join(leaked, "dist"), { recursive: true });
  writeFileSync(
    join(leaked, "dist", "index.js"),
    `-----BEGIN PRIVATE KEY-----\n${"A".repeat(64)}\n${"B".repeat(64)}\n-----END PRIVATE KEY-----\n`,
  );
  writeFileSync(join(leaked, "dist", "index.d.ts"), "export {};\n");
  rejected = false;
  try {
    validateAndHashStage(leaked, manifest);
  } catch {
    rejected = true;
  }
  if (!rejected) throw new Error("High-confidence secret content was not rejected.");

  const keyHandlingSource = join(root, "key-handling-source");
  mkdirSync(join(keyHandlingSource, "dist"), { recursive: true });
  writeFileSync(
    join(keyHandlingSource, "dist", "index.js"),
    'export const header = "-----BEGIN PRIVATE KEY-----\\n" + generatedBytes;\n',
  );
  writeFileSync(join(keyHandlingSource, "dist", "index.d.ts"), "export {};\n");
  validateAndHashStage(keyHandlingSource, manifest);

  console.log("Package staging integrity probes passed.");
} finally {
  rmSync(root, { recursive: true, force: true });
}
