/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.xsom;

import com.sun.xml.xsom.impl.scd.Iterators;
import com.sun.xml.xsom.impl.scd.ParseException;
import com.sun.xml.xsom.impl.scd.SCDImpl;
import com.sun.xml.xsom.impl.scd.SCDParser;
import com.sun.xml.xsom.impl.scd.Step;
import com.sun.xml.xsom.impl.scd.TokenMgrError;
import com.sun.xml.xsom.util.DeferedCollection;

import javax.xml.namespace.NamespaceContext;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * Schema Component Designator (SCD).
 *
 * <p>
 * SCD for schema is what XPath is for XML. SCD allows you to select a schema component(s)
 * from a schema component(s).
 *
 * <p>
 * See <a href="http://www.w3.org/TR/2005/WD-xmlschema-ref-20050329/">XML Schema: Component Designators</a>.
 * This implementation is based on 03/29/2005 working draft.
 *
 * @author Kohsuke Kawaguchi
 */
public abstract class SCD {

    /**
     * Default constructor.
     */
    protected SCD () {}

    /**
     * Parses the string representation of SCD.
     *
     * <p>
     * This method involves parsing the path expression and preparing the in-memory
     * structure, so this is useful when you plan to use the same SCD against
     * different context node multiple times.
     *
     * <p>
     * If you want to evaluate SCD just once, use {@link XSComponent#select} methods.
     *
     * @param path
     *      the string representation of SCD, such as "/foo/bar".
     * @param nsContext
     *      Its {@link NamespaceContext#getNamespaceURI(String)} is used
     *      to resolve prefixes in the SCD to the namespace URI.
     */
    public static SCD create(String path, NamespaceContext nsContext) throws java.text.ParseException {
        try {
            SCDParser p = new SCDParser(path,nsContext);
            List<?> list = p.RelativeSchemaComponentPath();
            return new SCDImpl(path,list.toArray(new Step[0]));
        } catch (TokenMgrError e) {
            throw setCause(new java.text.ParseException(e.getMessage(), -1 ),e);
        } catch (ParseException e) {
            throw setCause(new java.text.ParseException(e.getMessage(), e.currentToken.beginColumn ),e);
        }
    }

    private static java.text.ParseException setCause(java.text.ParseException e, Throwable x) {
        e.initCause(x);
        return e;
    }

    /**
     * Evaluates the SCD against the given context node and
     * returns the matched nodes.
     *
     * @return
     *      could be empty but never be null.
     */
    public final Collection<XSComponent> select(XSComponent contextNode) {
        return new DeferedCollection<>(select(Iterators.singleton(contextNode)));
    }

    /**
     * Evaluates the SCD against the whole schema and
     * returns the matched nodes.
     *
     * <p>
     * This method is here because {@link XSSchemaSet}
     * doesn't implement {@link XSComponent}.
     *
     * @return
     *      could be empty but never be null.
     */
    public final Collection<XSComponent> select(XSSchemaSet contextNode) {
        return select(contextNode.getSchemas());
    }

    /**
     * Evaluates the SCD against the given context node and
     * returns the matched node.
     *
     * @return
     *      null if the SCD didn't match anything. If the SCD matched more than one node,
     *      the first one will be returned.
     */
    public final XSComponent selectSingle(XSComponent contextNode) {
        Iterator<XSComponent> r = select(Iterators.singleton(contextNode));
        if(r.hasNext())     return r.next();
        return null;
    }

    /**
     * Evaluates the SCD against the whole schema set and
     * returns the matched node.
     *
     * @return
     *      null if the SCD didn't match anything. If the SCD matched more than one node,
     *      the first one will be returned.
     */
    public final XSComponent selectSingle(XSSchemaSet contextNode) {
        Iterator<XSComponent> r = select(contextNode.iterateSchema());
        if(r.hasNext())     return r.next();
        return null;
    }

    /**
     * Evaluates the SCD against the given set of context nodes and
     * returns the matched nodes.
     *
     * @param contextNodes
     *      {@link XSComponent}s that represent the context node against
     *      which  is evaluated.
     *
     * @return
     *      could be empty but never be null.
     */
    public abstract Iterator<XSComponent> select(Iterator<? extends XSComponent> contextNodes);

    /**
     * Evaluates the SCD against the given set of context nodes and
     * returns the matched nodes.
     *
     * @param contextNodes
     *      {@link XSComponent}s that represent the context node against
     *      which  is evaluated.
     *
     * @return
     *      could be empty but never be null.
     */
    public final Collection<XSComponent> select(Collection<? extends XSComponent> contextNodes) {
        return new DeferedCollection<>(select(contextNodes.iterator()));
    }

    /**
     * Returns the textual SCD representation as given to {@link SCD#create(String, NamespaceContext)}.
     */
    public abstract String toString();
}
