import ContextCache from "./ContextCache.js";
import path from "path";

function formatTimeSinceInSeconds(start) {
    return Math.ceil((performance.now() - start) / 100) / 10;
}

function serveResult (result, fileName, res, next) {
    let bundle, error;
    try {
      for (const out of result.outputFiles) {
        if (path.basename(out.path) === fileName) {
          bundle = out.text;
        }
      }
    } catch(e) {
      error = e;
    }
  
    if (!bundle) {
      next(new Error(`Failed to generate bundle: ${fileName}`, {
        cause: error
      }));
      return;
    }
  
    res.append("Cache-Control", "max-age=0");
    res.append("Content-Type", "application/javascript");
    res.send(bundle);
  };

function createRoute(app, name, route, context, dependantCaches) {
    const cache = new ContextCache(context);
    app.get(route, async function (req, res, next) {
      // Multiple files may be requested at this path, calling this function in quick succession.
      // Await the previous build before re-building again.
      await cache.promise;
  
      if (!cache.isBuilt()) {
        try {
          const start = performance.now();
          if (dependantCaches) {
            await Promise.all(
              dependantCaches.map((dependantCache) => {
                if (!dependantCache.isBuilt()) {
                  return dependantCache.rebuild();
                }
              })
            );
          }
          await cache.rebuild();
          console.log(
            `Built ${name} in ${formatTimeSinceInSeconds(start)} seconds.`
          );
        } catch (e) {
          next(e);
        }
      }
  
      return serveResult(cache.result, path.basename(req.originalUrl), res, next);
    });
  
    return cache;
  }

export default createRoute;