"use strict";

const FENCE_OPEN_RE = /^\s{0,3}(`{3,}|~{3,})(.*)$/;
const DIRECTIVE_RE = /<!--\s*migration:(skip-next|skip-block|resume)\s*-->/;
const COMMENT_OPEN = /<!--/g;
const COMMENT_CLOSE = /-->/g;

/**
 * Scan markdown content and tag each line with its structural context.
 *
 * @param {string} content
 * @returns {{
 *   lines: Array<{
 *     num: number,
 *     text: string,
 *     inFence: boolean,
 *     inHtmlComment: boolean,
 *     inFrontmatter: boolean
 *   }>,
 *   directives: Array<{
 *     kind: 'skip-next'|'skip-block'|'resume',
 *     line: number
 *   }>
 * }}
 */
function scanMarkdown(content) {
  const rawLines = content.split(/\r?\n/);
  const lines = [];
  const directives = [];

  let inFence = false;
  let fenceChar = null;
  let fenceLen = 0;
  let inFrontmatter = false;
  let htmlCommentOpen = 0;

  for (let i = 0; i < rawLines.length; i++) {
    const text = rawLines[i];
    const num = i + 1;
    const htmlCommentAtLineStart = htmlCommentOpen > 0;

    if (num === 1 && text === "---") {
      inFrontmatter = true;
      lines.push({
        num,
        text,
        inFence: false,
        inHtmlComment: false,
        inFrontmatter: true,
      });
      continue;
    }

    if (inFrontmatter) {
      if (text === "---") {
        inFrontmatter = false;
        lines.push({
          num,
          text,
          inFence: false,
          inHtmlComment: false,
          inFrontmatter: true,
        });
      } else {
        lines.push({
          num,
          text,
          inFence: false,
          inHtmlComment: false,
          inFrontmatter: true,
        });
      }
      continue;
    }

    const fenceMatch = text.match(FENCE_OPEN_RE);
    if (fenceMatch) {
      const marker = fenceMatch[1];
      const ch = marker[0];
      const len = marker.length;
      if (!inFence) {
        inFence = true;
        fenceChar = ch;
        fenceLen = len;
        lines.push({
          num,
          text,
          inFence: true,
          inHtmlComment: htmlCommentAtLineStart,
          inFrontmatter: false,
        });
        continue;
      } else if (ch === fenceChar && len >= fenceLen) {
        inFence = false;
        fenceChar = null;
        fenceLen = 0;
        lines.push({
          num,
          text,
          inFence: true,
          inHtmlComment: htmlCommentAtLineStart,
          inFrontmatter: false,
        });
        continue;
      }
    }

    const opens = (text.match(COMMENT_OPEN) || []).length;
    const closes = (text.match(COMMENT_CLOSE) || []).length;
    htmlCommentOpen = Math.max(0, htmlCommentOpen + opens - closes);

    if (!inFence) {
      const d = text.match(DIRECTIVE_RE);
      if (d) directives.push({ kind: d[1], line: num });
    }

    lines.push({
      num,
      text,
      inFence,
      inFrontmatter: false,
      inHtmlComment: htmlCommentAtLineStart || htmlCommentOpen > 0,
    });
  }

  return { lines, directives };
}

module.exports = { scanMarkdown };
