import { List } from '../utils/List.js';

function getFirstMatchNode(matchNode) {
  if ('node' in matchNode) {
    return matchNode.node;
  }

  return getFirstMatchNode(matchNode.match[0]);
}

function getLastMatchNode(matchNode) {
  if ('node' in matchNode) {
    return matchNode.node;
  }

  return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
}

export function matchFragments(lexer, ast, match, type, name) {
  function findFragments(matchNode) {
    if (
      matchNode.syntax !== null &&
      matchNode.syntax.type === type &&
      matchNode.syntax.name === name
    ) {
      const start = getFirstMatchNode(matchNode);
      const end = getLastMatchNode(matchNode);

      lexer.syntax.walk(ast, function (node, item, list) {
        if (node === start) {
          const nodes = new List();

          do {
            nodes.appendData(item.data);

            if (item.data === end) {
              break;
            }

            item = item.next;
          } while (item !== null);

          fragments.push({
            parent: list,
            nodes,
          });
        }
      });
    }

    if (Array.isArray(matchNode.match)) {
      matchNode.match.forEach(findFragments);
    }
  }

  const fragments = [];

  if (match.matched !== null) {
    findFragments(match.matched);
  }

  return fragments;
}