import fs from "node:fs";
import path from "node:path";

// Files that need renaming because they cause issues in the repo/pack.
// npm renames .gitignore during pack (npm/cli#5756).
// pnpm-workspace.yaml causes the template dir to be treated as a workspace member.
// prepack copies these to their safe names; scaffold time restores the originals.
const RENAME_MAP: Record<string, string> = {
  __dot__gitignore: ".gitignore",
  "__pnpm-workspace.yaml": "pnpm-workspace.yaml",
};

export function copyTemplateDir(
  srcDir: string,
  destDir: string,
  replacements: Record<string, string>,
  placeholderFiles: Set<string>,
): void {
  for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
    const srcPath = path.join(srcDir, entry.name);
    const destName = RENAME_MAP[entry.name] ?? entry.name;
    const destPath = path.join(destDir, destName);

    // Only needed for local dev — published packages won't contain node_modules.
    if (entry.name === "node_modules") continue;

    if (entry.isDirectory()) {
      fs.mkdirSync(destPath, { recursive: true });
      copyTemplateDir(srcPath, destPath, replacements, placeholderFiles);
    } else {
      if (fs.existsSync(destPath)) continue;
      if (placeholderFiles.has(entry.name)) {
        let content = fs.readFileSync(srcPath, "utf-8");
        for (const [from, to] of Object.entries(replacements)) {
          content = content.replaceAll(from, to);
        }
        fs.writeFileSync(destPath, content);
      } else {
        fs.copyFileSync(srcPath, destPath);
      }
    }
  }
}
