#!/usr/bin/env node
// Copy the repo-root runtime config assets that `@origintrail-official/dkg`
// (packages/cli) ships in its published tarball: the per-network overlays
// (`network/*.json`) and `project.json`.
//
// These files live at the repo root but must be present INSIDE packages/cli at
// pack time because `packages/cli/package.json#files` lists "network" and
// "project.json" — and npm silently omits `files` entries that don't exist on
// disk when the tarball is built.
//
// Historically this copy was a side effect of the `build` script. That made it
// cache-unsafe: `turbo.json` declares the build task's outputs as `dist/**`
// only, so on a turbo cache hit `dist/` was restored but the copy never re-ran,
// and the published tarball shipped without `network/` + `project.json`
// (regression in 10.0.4 — npm-installed nodes then fell back to built-in
// defaults with no network overlay). Running this from `prepack` as well makes
// materialization unconditional at pack time, independent of the build cache.
//
// Paths are resolved from `rootDir` (default: this script's own location), so
// it is correct regardless of the current working directory (prepack runs with
// cwd = packages/cli; a manual run may use the repo root).

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const SCRIPT_PATH = fileURLToPath(import.meta.url);
const DEFAULT_ROOT_DIR = path.resolve(path.dirname(SCRIPT_PATH), '..');

function enumerateNetworkOverlays(sourceNetworkDir) {
  if (!fs.existsSync(sourceNetworkDir) || !fs.statSync(sourceNetworkDir).isDirectory()) {
    return null;
  }
  return fs
    .readdirSync(sourceNetworkDir)
    .filter((file) => file.endsWith('.json'))
    .sort();
}

/**
 * Read + VALIDATE the CLI runtime-asset manifest from the repo root — the single
 * FAIL-CLOSED source of truth shared by the pack-time copy (below) and the
 * `release:verify-pack` preflight (scripts/release-packages.mjs). Throws if the
 * source tree can't produce the full set (network/ missing or empty, or
 * project.json absent), so the verifier can never silently build a required list
 * that omits the network overlays — it enforces exactly the same invariant as
 * the copier. `build-info.json` is NOT in the manifest: it is generated by
 * `release:build-info`, so the verifier appends it as a release-only extension.
 */
export function cliRuntimeAssetManifest({ rootDir = DEFAULT_ROOT_DIR } = {}) {
  const sourceNetworkDir = path.join(rootDir, 'network');
  const sourceProjectJson = path.join(rootDir, 'project.json');
  const overlays = enumerateNetworkOverlays(sourceNetworkDir);
  if (overlays === null) {
    throw new Error(`copy-cli-runtime-assets: repo-root network/ directory not found at ${sourceNetworkDir}`);
  }
  if (overlays.length === 0) {
    throw new Error(`copy-cli-runtime-assets: no network/*.json overlays found in ${sourceNetworkDir}`);
  }
  if (!fs.existsSync(sourceProjectJson)) {
    throw new Error(`copy-cli-runtime-assets: repo-root project.json not found at ${sourceProjectJson}`);
  }
  return {
    rootDir,
    sourceNetworkDir,
    sourceProjectJson,
    networkJsonFiles: overlays,
    // package-relative paths that MUST appear inside the published tarball
    relPaths: ['project.json', ...overlays.map((file) => `network/${file}`)],
  };
}

/**
 * Materialize packages/cli's runtime-config assets from the repo root.
 *
 * Validates via the shared manifest (fails loudly on a broken source tree), then
 * MIRRORS the target `network/` directory — removed and recreated so a root
 * overlay that was later deleted cannot linger in `packages/cli/network` and
 * leak into the tarball (files: ["network"] ships the whole directory).
 */
export function copyCliRuntimeAssets({ rootDir = DEFAULT_ROOT_DIR } = {}) {
  const { sourceNetworkDir, sourceProjectJson, networkJsonFiles } = cliRuntimeAssetManifest({ rootDir });
  const cliDir = path.join(rootDir, 'packages', 'cli');
  const targetNetworkDir = path.join(cliDir, 'network');
  const targetProjectJson = path.join(cliDir, 'project.json');

  fs.rmSync(targetNetworkDir, { recursive: true, force: true });
  fs.mkdirSync(targetNetworkDir, { recursive: true });
  for (const file of networkJsonFiles) {
    fs.copyFileSync(path.join(sourceNetworkDir, file), path.join(targetNetworkDir, file));
  }
  fs.copyFileSync(sourceProjectJson, targetProjectJson);

  return { rootDir, cliDir, networkJsonFiles };
}

const invokedDirectly = process.argv[1] && path.resolve(process.argv[1]) === SCRIPT_PATH;
if (invokedDirectly) {
  try {
    const { rootDir, cliDir, networkJsonFiles } = copyCliRuntimeAssets();
    const relTarget = path.relative(rootDir, cliDir) || '.';
    // Log to stderr, not stdout: this runs as `prepack`, and `npm pack --json`
    // emits its machine-readable report on stdout — anything we print there
    // would corrupt it for the `release:verify-pack` preflight that parses it.
    console.error(
      `copy-cli-runtime-assets: copied ${networkJsonFiles.length} network overlay(s) + project.json into ${relTarget}/`,
    );
  } catch (err) {
    console.error(err instanceof Error ? err.message : String(err));
    process.exit(1);
  }
}
