import fs from 'fs-extra';
import { glob } from 'glob';
import MarkdownIt from 'markdown-it';

const errorTitle = 'Invalid JSON in fenced code block';
const errorBody =
  'Fix this manually by ensuring each block is a valid, complete JSON document.';
const markdownGlob = '{docs,lib}/**/*.md';
const markdown = new MarkdownIt('zero');

let issues = 0;

markdown.enable(['fence']);

/**
 *
 * @param {string} file
 * @param {import('markdown-it').Token} token
 */
function checkValidJson(file, token) {
  const start = token.map ? token.map[0] + 1 : 0;
  const end = token.map ? token.map[1] + 1 : 0;

  try {
    JSON.parse(token.content);
  } catch (err) {
    issues += 1;
    if (process.env.CI) {
      console.log(
        `::error file=${file},line=${start},endLine=${end},title=${errorTitle}::${err.message}. ${errorBody}`,
      );
    } else {
      console.log(
        `${errorTitle} (${file} lines ${start}-${end}): ${err.message}`,
      );
    }
  }
}

/**
 *
 * @param {string} file
 */
async function processFile(file) {
  const text = await fs.readFile(file, 'utf8');
  const tokens = markdown.parse(text, undefined);

  tokens.forEach((token) => {
    if (token.type === 'fence' && token.info === 'json') {
      checkValidJson(file, token);
    }
  });
}

await (async () => {
  const files = await glob(markdownGlob);

  for (const file of files) {
    await processFile(file);
  }

  if (issues) {
    console.error(
      `${issues} issues found. ${errorBody} See above for lines affected.`,
    );
    process.exit(1);
  }
})();