/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */

package net.ranides.assira.xml;

import java.util.function.Function;
import java.util.function.Predicate;
import net.ranides.assira.xml.impl.W3Selectors;

/**
 * XMLSelector intenface can be used in two ways:
 *  - to scan recursively provided context and find all matching elements
 *  - to test provided context and tell if it matches criteria required by this selector
 *
 * In other words, can be used both as function or as predicate.
 *
 * There are few built-in selectors, for example CSS or XPATH.
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
public interface XMLSelector extends Function<XMLContext, XMLElements>, Predicate<XMLContext> {

    @Override
    XMLElements apply(XMLContext context);

    @Override
    boolean test(XMLContext context);

    /**
     * Factory: this method supports 3 types of selectors: CSS, XPATH and "byTagName"
     * First, it detects type of selector.
     *  - if you pass simple tag name, it will call {@link #name}.
     *  - if you pass CSS expression, it will call {@link #css}
     *  - if you pass XPATH prefixed by "? " text, it will call {@link #xpath}.
     *
     * To reiterate: XPATH expressions must be prefixed by "? "
     *
     * @param selector selector
     * @return XMLSelector
     */
    static XMLSelector compile(String selector) {
        return W3Selectors.compile(selector);
    }

    /**
     * Creates new selector using CSS syntax.
     *
     * @param selector selector
     * @return XMLSelector
     */
    static XMLSelector css(String selector) {
        return W3Selectors.css(selector);
    }

    /**
     * Creates new selector using XPATH syntax.
     *
     * Please note, that altough {@link #compile} requires "? " prefix, this method DOES NOT.
     * Just pass ordinary correct XPATH expression.
     *
     * @param selector selector
     * @return XMLSelector
     */
    static XMLSelector xpath(String selector) {
        return W3Selectors.xpath(selector);
    }

    /**
     * Creates new selector which can be used to match direct children by tagname.
     * Just pass ordinary tag name as argument.
     *
     * @param selector selector
     * @return XMLSelector
     */
    static XMLSelector name(String selector) {
        return W3Selectors.name(selector);
    }
    
}
