// we need a custom renderer for code blocks cause we have a slightly non compliant
// format with special handling for text and so on

const TEXT_CODE_CLASSES = ["text", "pre", "plain"];

function render(tokens, idx, options, env, slf, md) {
  let token = tokens[idx],
    info = token.info ? md.utils.unescapeAll(token.info) : "",
    langName = md.options.discourse.defaultCodeLang,
    className,
    escapedContent = md.utils.escapeHtml(token.content);

  if (info) {
    // strip off any additional languages
    info = info.trim().split(/\s+/g)[0];
  }

  const acceptableCodeClasses = md.options.discourse.acceptableCodeClasses;
  if (
    acceptableCodeClasses &&
    info &&
    acceptableCodeClasses.indexOf(info) !== -1
  ) {
    langName = info;
  }

  className =
    TEXT_CODE_CLASSES.indexOf(info) !== -1
      ? "lang-nohighlight"
      : "lang-" + langName;

  return `<pre><code class="${className}">${escapedContent}</code></pre>\n`;
}

export function setup(helper) {
  helper.registerOptions((opts, siteSettings) => {
    opts.defaultCodeLang = siteSettings.default_code_lang;
    opts.acceptableCodeClasses = (siteSettings.highlighted_languages || "")
      .split("|")
      .filter(Boolean)
      .concat(["auto", "nohighlight"]);
  });

  helper.allowList({
    custom(tag, name, value) {
      if (tag === "code" && name === "class") {
        const m = /^lang\-(.+)$/.exec(value);
        if (m) {
          return helper.getOptions().acceptableCodeClasses.indexOf(m[1]) !== -1;
        }
      }
    },
  });

  helper.registerPlugin((md) => {
    md.renderer.rules.fence = (tokens, idx, options, env, slf) =>
      render(tokens, idx, options, env, slf, md);
  });
}
