import {
  projectFilePath,
  type ProjectStorageProvider,
} from '@learnitive/project-storage';
import type { LatexCompileFile } from './types';

const INTERNAL_PREFIXES = ['.git/', '.interactive-generated/cache/'] as const;

function shouldCompilePath(path: string): boolean {
  return !INTERNAL_PREFIXES.some(
    (prefix) => path === prefix.slice(0, -1) || path.startsWith(prefix),
  );
}

/**
 * Reads a stable binary snapshot of the project for a compile. Unknown and
 * binary project files are intentionally retained; TeX packages/classes often
 * load data using extensions Learnitive does not otherwise understand.
 */
export async function collectProjectCompileFiles(
  storage: ProjectStorageProvider,
  rootFile: string,
  signal?: AbortSignal,
): Promise<{ rootFile: ReturnType<typeof projectFilePath>; files: LatexCompileFile[] }> {
  signal?.throwIfAborted();
  const root = projectFilePath(rootFile);
  const entries = await storage.listEntries(signal);
  const files: LatexCompileFile[] = [];
  let rootFound = false;

  for (const entry of entries) {
    signal?.throwIfAborted();
    if (entry.kind !== 'file' || !shouldCompilePath(entry.path)) {
      continue;
    }
    const content = await storage.readFile(entry.path, signal);
    if (content === undefined) {
      throw new Error(`Project file disappeared while compiling: ${entry.path}`);
    }
    files.push({ path: entry.path, content: content.slice() });
    if (entry.path === root) {
      rootFound = true;
    }
  }

  if (!rootFound) {
    throw new Error(`LaTeX root file was not found: ${root}`);
  }

  return { rootFile: root, files };
}
