/**
 * @license
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 type {
  Matcher,
  RangeSelector,
  Selector,
} from '@apache-annotator/selector';
import { ownerDocument } from '../owner-document';
import { toRange } from '../range-node-conversion';
import { cartesian } from './cartesian';

/**
 * Find the range(s) corresponding to the given {@link RangeSelector}.
 *
 * As a RangeSelector itself nests two further selectors, one needs to pass a
 * `createMatcher` function that will be used to process those nested selectors.
 *
 * The function is curried, taking first the `createMatcher` function, then the
 * selector, and then the scope.
 *
 * As there may be multiple matches for the start & end selectors, the resulting
 * matcher will return an (async) iterable, that produces a match for each
 * possible pair of matches of the nested selectors (except those where its end
 * would precede its start). *(Note that this behaviour is a rather free
 * interpretation of the Web Annotation Data Model spec, which is silent about
 * the possibility of multiple matches for RangeSelectors)*
 *
 * @example
 * By using a matcher for {@link TextQuoteSelector}s, one
 * could create a matcher for text quotes with ellipsis to select a phrase
 * “ipsum … amet,”:
 * ```
 * const selector = {
 *   type: 'RangeSelector',
 *   startSelector: {
 *     type: 'TextQuoteSelector',
 *     exact: 'ipsum ',
 *   },
 *   endSelector: {
 *     type: 'TextQuoteSelector',
 *     // Because the end of a RangeSelector is *exclusive*, we will present the
 *     // latter part of the quote as the *prefix* so it will be part of the
 *     // match.
 *     exact: '',
 *     prefix: ' amet,',
 *   }
 * };
 * const createRangeSelectorMatcher =
 *   makeCreateRangeSelectorMatcher(createTextQuoteMatcher);
 * const match = createRangeSelectorMatcher(selector)(document.body);
 * console.log(match)
 * // ⇒ Range { startContainer: #text, startOffset: 6, endContainer: #text,
 * //   endOffset: 27, … }
 * ```
 *
 * @example
 * To support RangeSelectors that might themselves contain RangeSelectors,
 * recursion can be created by supplying the resulting matcher creator function
 * as the `createMatcher` parameter:
 * ```
 * const createWhicheverMatcher = (selector) => {
 *   const innerCreateMatcher = {
 *     TextQuoteSelector: createTextQuoteSelectorMatcher,
 *     TextPositionSelector: createTextPositionSelectorMatcher,
 *     RangeSelector: makeCreateRangeSelectorMatcher(createWhicheverMatcher),
 *   }[selector.type];
 *   return innerCreateMatcher(selector);
 * });
 * ```
 *
 * @param createMatcher - The function used to process nested selectors.
 * @returns A function that, given a RangeSelector `selector`, creates a {@link
 * Matcher} function that can apply it to a given `scope`.
 *
 * @public
 */
export function makeCreateRangeSelectorMatcher(
  createMatcher: <T extends Selector, TMatch extends Node | Range>(selector: T)
    => Matcher<Node | Range, TMatch>,
): (selector: RangeSelector) => Matcher<Node | Range, Range> {
  return function createRangeSelectorMatcher(selector) {
    const startMatcher = createMatcher(selector.startSelector);
    const endMatcher = createMatcher(selector.endSelector);

    return async function* matchAll(scope) {
      const startMatches = startMatcher(scope);
      const endMatches = endMatcher(scope);

      const pairs = cartesian(startMatches, endMatches);

      for await (let [start, end] of pairs) {
        start = toRange(start);
        end = toRange(end);

        const result = ownerDocument(scope).createRange();
        result.setStart(start.startContainer, start.startOffset);
        // Note that a RangeSelector’s match *excludes* the endSelector’s match,
        // hence we take the end’s startContainer & startOffset.
        result.setEnd(end.startContainer, end.startOffset);

        if (!result.collapsed) yield result;
      }
    };
  };
}
