import { Middleware } from 'koa';
import path from 'path';
import { toBrowserPath } from '../utils';
import { Logger } from '../logger/Logger';

/**
 * Serves index.html when a non-file request within the scope of the app index is made.
 * This allows SPA routing.
 */
export function historyApiFallbackMiddleware(
  appIndex: string,
  rootDir: string,
  logger: Logger,
): Middleware {
  const resolvedAppIndex = path.resolve(appIndex);
  const relativeAppIndex = path.relative(rootDir, resolvedAppIndex);
  const appIndexBrowserPath = `/${toBrowserPath(relativeAppIndex)}`;
  const appIndexBrowserPathPrefix = path.dirname(appIndexBrowserPath);

  return (ctx, next) => {
    if (ctx.method !== 'GET' || path.extname(ctx.path)) {
      // not a GET, or a direct file request
      return next();
    }

    if (!ctx.headers || typeof ctx.headers.accept !== 'string') {
      return next();
    }

    if (ctx.headers.accept.includes('application/json')) {
      return next();
    }

    if (!(ctx.headers.accept.includes('text/html') || ctx.headers.accept.includes('*/*'))) {
      return next();
    }

    if (!ctx.url.startsWith(appIndexBrowserPathPrefix)) {
      return next();
    }

    // rewrite url and let static serve take it further
    logger.debug(`Rewriting ${ctx.url} to app index ${appIndexBrowserPath}`);
    ctx.url = appIndexBrowserPath;
    return next();
  };
}