/**
 * @license
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import { createRangeSelector } from '@annotator/range';
import { createAnySelectorCreator } from '@annotator/selector';
import { createTextQuoteSelector } from '@annotator/text';

const allSelectorTypes = {
  TextQuoteSelector: createTextQuoteSelector,
  RangeSelector: createRangeSelector,
};

const selectorFunc = createAnySelectorCreator(allSelectorTypes)();

/**
 * Locate a selector.
 * @param {Node} root node
 * @param {Selector} descriptor
 * @return {Range}
 */
export async function* search(root, descriptor) {
  for (const node of nodeIterator(root)) {
    if (!node.nodeValue) continue;

    const matches = selectorFunc({
      descriptors: [descriptor],
      context: node.nodeValue,
    });
    for await (let match of matches) {
      const startIndex = match.index;
      const endIndex = startIndex + match[0].length;
      const range = document.createRange();
      range.setStart(node, startIndex);
      range.setEnd(node, endIndex);
      yield range;
    }
  }
}

/**
 * Iterate over the nodes of a sub-tree of the document.
 * @param {Node} node
 */
function* nodeIterator(node) {
  yield node;

  for (const child of node.childNodes) {
    yield* nodeIterator(child);
  }
}
