import * as path from "path";
import * as fs from "fs";
import * as mkdirp from "mkdirp";

// Utility function to copy directory recursively
export function copyDir(src: string, dest: string) {
  if (!fs.existsSync(dest)) mkdirp.sync(dest);
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
    const srcPath = path.join(src, entry.name);
    const destPath = path.join(dest, entry.name);
    if (entry.isDirectory()) {
      copyDir(srcPath, destPath);
    } else {
      fs.copyFileSync(srcPath, destPath);
    }
  }
}

// Download all files from a GCS Bucket prefix to a local folder
export async function downloadS3Folder(
  bucket: any,
  prefix: string,
  localPath: string
) {
  const [files] = await bucket.getFiles({ prefix });
  for (const file of files) {
    const relPath = file.name.replace(prefix, "");
    if (!relPath) continue;
    const outPath = path.join(localPath, relPath);
    mkdirp.sync(path.dirname(outPath));
    // esling-disable-next-line
    const [buf] = await file.download();
    fs.writeFileSync(outPath, buf);
  }
}

// Generate file list for manifest, given a folder
export function getFilesList(folder: string, base: string) {
  let list: string[] = [];
  const files = fs.readdirSync(folder, { withFileTypes: true });
  for (const file of files) {
    const filePath = path.join(folder, file.name);
    if (file.isDirectory()) {
      // esling-disable-next-line
      list = list.concat(getFilesList(filePath, path.join(base, file.name)));
    } else {
      list.push(
        `<file href="${path.join(base, file.name).replace(/\\/g, "/")}" />`
      );
    }
  }
  return list;
}

// Read course metadata from learn.json
export async function getCourseMetadata(bucket: any, courseSlug: string) {
  const [learnBuf] = await bucket
    .file(`courses/${courseSlug}/learn.json`)
    .download();
  return JSON.parse(learnBuf.toString());
}
