/*
 * 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.
 */
package org.apache.sis.internal.storage.xml.stream;

import java.util.Date;
import java.util.Map;
import java.util.List;
import java.util.Arrays;
import java.util.Spliterator;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.time.temporal.Temporal;
import java.time.format.DateTimeParseException;
import java.net.URI;
import java.io.IOException;
import java.io.EOFException;
import java.net.URISyntaxException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import org.apache.sis.internal.jaxb.Context;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.internal.util.StandardDateFormat;
import org.apache.sis.internal.storage.io.IOUtilities;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreContentException;
import org.apache.sis.util.collection.BackingStoreException;
import org.apache.sis.util.resources.Errors;

// Branch-dependent imports
import org.apache.sis.feature.AbstractFeature;


/**
 * Base class of Apache SIS readers of XML files using STAX parser.
 * This class is itself an spliterator over all {@code Feature} instances found in the XML file,
 * with the following restrictions:
 *
 * <ul>
 *   <li>{@link #tryAdvance(Consumer)} shall returns the features in the order they are declared in the XML file.</li>
 *   <li>{@code tryAdvance(Consumer)} shall not return {@code null} value.</li>
 *   <li>Modifications of the XML file are not allowed while an iteration is in progress.</li>
 *   <li>A {@code StaxStreamReader} instance can iterate over the features only once;
 *       if a new iteration is wanted, a new {@code StaxStreamReader} instance must be created.</li>
 * </ul>
 *
 * This is a helper class for {@link org.apache.sis.storage.DataStore} implementations.
 * Readers for a given specification should extend this class and implement methods as
 * in the following example:
 *
 * <p>Example:</p>
 * {@preformat java
 *     public class UserObjectReader extends StaxStreamReader {
 *         UserObjectReader(StaxDataStore owner) throws ... {
 *             super(owner);
 *         }
 *
 *         &#64;Override
 *         public boolean tryAdvance(Consumer<? super Feature> action) throws BackingStoreException {
 *             if (endOfFile) {
 *                 return false;
 *             }
 *             Feature f = ...;         // Actual STAX read operations.
 *             action.accept(f);
 *             return true;
 *         }
 *     }
 * }
 *
 * Readers can be used like below:
 *
 * {@preformat java
 *     Consumer<Feature> consumer = ...;
 *     try (UserObjectReader reader = new UserObjectReader(dataStore)) {
 *         reader.forEachRemaining(consumer);
 *     }
 * }
 *
 * <div class="section">Multi-threading</div>
 * This class and subclasses are not tread-safe. Synchronization shall be done by the {@code DataStore}
 * that contains the {@code StaxStreamReader} instance.
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.8
 * @module
 */
public abstract class StaxStreamReader extends StaxStreamIO implements XMLStreamConstants, Spliterator<AbstractFeature>, Runnable {
    /**
     * The XML stream reader.
     */
    protected final XMLStreamReader reader;

    /**
     * {@code true} if the {@link #reader} already moved to the next element. This happen if {@link #unmarshal(Class)}
     * has been invoked. In such case, the next call to {@link XMLStreamReader#next()} needs to be replaced by a call
     * to {@link XMLStreamReader#getEventType()}.
     */
    private boolean isNextDone;

    /**
     * The unmarshaller reserved to this reader usage,
     * created only when first needed and kept until this reader is closed.
     *
     * @see #unmarshal(Class)
     */
    private Unmarshaller unmarshaller;

    /**
     * Creates a new XML reader for the given data store.
     *
     * @param  owner  the data store for which this reader is created.
     * @throws DataStoreException if the input type is not recognized or the data store is closed.
     * @throws XMLStreamException if an error occurred while opening the XML file.
     * @throws IOException if an error occurred while preparing the input stream.
     * @throws Exception if another kind of error occurred while closing a previous stream.
     */
    @SuppressWarnings("ThisEscapedInObjectConstruction")
    protected StaxStreamReader(final StaxDataStore owner) throws Exception {
        super(owner);
        reader = owner.createReader(this);      // Okay because will not store the 'this' reference.
    }

    /**
     * Returns the characteristics of the iteration over feature instances.
     * The iteration is assumed {@link #ORDERED} in the declaration order in the XML file.
     * The iteration is {@link #NONNULL} (i.e. {@link #tryAdvance(Consumer)} is not allowed
     * to return null value) and {@link #IMMUTABLE} (i.e. we do not support modification of
     * the XML file while an iteration is in progress).
     *
     * @return characteristics of iteration over the features in the XML file.
     */
    @Override
    public int characteristics() {
        return ORDERED | NONNULL | IMMUTABLE;
    }

    /**
     * Performs the given action on the next feature instance, or returns {@code null} if there is no more
     * feature to parse.
     *
     * @param  action  the action to perform on the next feature instances.
     * @return {@code true} if a feature has been found, or {@code false} if we reached the end of XML file.
     * @throws BackingStoreException if an error occurred while parsing the next feature instance.
     *         The cause may be {@link DataStoreException}, {@link IOException}, {@link URISyntaxException}
     *         or various {@link RuntimeException} among others.
     */
    @Override
    public abstract boolean tryAdvance(Consumer<? super AbstractFeature> action) throws BackingStoreException;

    /**
     * Returns {@code null} by default since non-binary XML files are hard to split.
     *
     * @return {@code null}.
     */
    @Override
    public Spliterator<AbstractFeature> trySplit() {
        return null;
    }

    /**
     * Returns the sentinel value meaning that the number of elements is too expensive to compute.
     *
     * @return {@link Long#MAX_VALUE}.
     */
    @Override
    public long estimateSize() {
        return Long.MAX_VALUE;
    }




    ////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                ////////
    ////////                Convenience methods for subclass implementations                ////////
    ////////                                                                                ////////
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Returns a XML stream reader over only a portion of the document, from given position inclusive
     * until the end of the given element exclusive. Nested elements of the same name, if any, will be
     * ignored.
     *
     * @param  tagName name of the tag to close.
     * @return a reader over a portion of the stream.
     * @throws XMLStreamException if this XML reader has been closed.
     */
    protected final XMLStreamReader getSubReader(final QName tagName) throws XMLStreamException {
        return new StreamReaderDelegate(reader) {
            /** Increased every time a nested element of the same name is found. */
            private int nested;

            /** Returns {@code false} if we reached the end of the sub-region. */
            @Override public boolean hasNext() throws XMLStreamException {
                return (nested >= 0) && super.hasNext();
            }

            /** Reads the next element in the sub-region. */
            @Override public int next() throws XMLStreamException {
                if (nested < 0) {
                    throw new NoSuchElementException();
                }
                final int t = super.next();
                switch (t) {
                    case START_ELEMENT: if (tagName.equals(getName())) nested++; break;
                    case END_ELEMENT:   if (tagName.equals(getName())) nested--; break;
                }
                return t;
            }
        };
    }

    /**
     * Moves the cursor the the first start element and verifies that it is the expected element.
     * This method is useful for skipping comments, entity declarations, <i>etc.</i> before the root element.
     *
     * <p>If the reader is already on a start element, then this method does not move forward.
     * Once a root element has been found, this method verifies that the namespace and local name
     * are the expected ones, or throws an exception otherwise.</p>
     *
     * @param  isNamespace  a predicate receiving the namespace in argument (which may be null)
     *                      and returning whether that namespace is the expected one.
     * @param  localName    the expected name of the root element.
     * @throws EOFException if no start element has been found before we reached the end of file.
     * @throws XMLStreamException if an error occurred while reading the XML stream.
     * @throws DataStoreContentException if the root element is not the expected one.
     */
    protected final void moveToRootElement(final Predicate<String> isNamespace, final String localName)
            throws EOFException, XMLStreamException, DataStoreContentException
    {
        if (!reader.isStartElement()) {
            do if (!reader.hasNext()) {
                throw new EOFException(endOfFile());
            } while (reader.next() != START_ELEMENT);
        }
        if (!isNamespace.test(reader.getNamespaceURI()) || !localName.equals(reader.getLocalName())) {
            throw new DataStoreContentException(errors().getString(
                    Errors.Keys.UnexpectedFileFormat_2, owner.getFormatName(), owner.getDisplayName()));
        }
    }

    /**
     * Skips all remaining elements until we reach the end of the given tag.
     * Nested tags of the same name, if any, are also skipped.
     *
     * <p>The current event when this method is invoked must be {@link #START_ELEMENT}.
     * After this method invocation, the current event will be {@link #END_ELEMENT}.</p>
     *
     * @param  tagName name of the tag to close.
     * @throws EOFException if end tag could not be found.
     * @throws XMLStreamException if an error occurred while reading the XML stream.
     */
    protected final void skipUntilEnd(final QName tagName) throws EOFException, XMLStreamException {
        assert reader.getEventType() == START_ELEMENT;
        isNextDone = false;
        int nested = 0;
        while (reader.hasNext()) {
            switch (reader.next()) {
                case START_ELEMENT: {
                    if (tagName.equals(reader.getName())) {
                        nested++;
                    }
                    break;
                }
                case END_ELEMENT: {
                    if (tagName.equals(reader.getName())) {
                        if (--nested < 0) return;
                    }
                    break;
                }
            }
        }
        throw new EOFException(endOfFile());
    }

    /**
     * Gets next parsing event. This method should be used instead of {@link XMLStreamReader#next()}
     * when the {@code while (next())} loop may contain call to the {@link #unmarshal(Class)} method.
     *
     * @return one of the {@link XMLStreamConstants}.
     * @throws XMLStreamException if an error occurred while fetching the next event.
     */
    protected final int next() throws XMLStreamException {
        if (!isNextDone) {
            return reader.next();       // This is the usual case.
        }
        isNextDone = false;
        return reader.getEventType();
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()},
     * or {@code null} if that value is null or empty.
     *
     * <p>The current event when this method is invoked must be {@link #START_ELEMENT}.
     * After this method invocation, the current event will be {@link #END_ELEMENT}.</p>
     *
     * @return the current text element, or {@code null} if empty.
     * @throws XMLStreamException if a text element can not be returned.
     */
    protected final String getElementText() throws XMLStreamException {
        String text = reader.getElementText();
        if (text != null) {
            text = text.trim();
            if (!text.isEmpty()) {
                return text;
            }
        }
        return null;
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()} as a URI,
     * or {@code null} if that value is null or empty.
     *
     * @return the current text element as a URI, or {@code null} if empty.
     * @throws XMLStreamException if a text element can not be returned.
     * @throws URISyntaxException if the text can not be parsed as a URI.
     */
    protected final URI getElementAsURI() throws XMLStreamException, URISyntaxException {
        final Context context = Context.current();
        return Context.converter(context).toURI(context, getElementText());
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()} as an integer,
     * or {@code null} if that value is null or empty.
     *
     * @return the current text element as an integer, or {@code null} if empty.
     * @throws XMLStreamException if a text element can not be returned.
     * @throws NumberFormatException if the text can not be parsed as an integer.
     */
    protected final Integer getElementAsInteger() throws XMLStreamException {
        final String text = getElementText();
        return (text != null) ? Integer.valueOf(text) : null;
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()} as a floating point number,
     * or {@code null} if that value is null or empty.
     *
     * @return the current text element as a floating point number, or {@code null} if empty.
     * @throws XMLStreamException if a text element can not be returned.
     * @throws NumberFormatException if the text can not be parsed as a floating point number.
     *
     * @see #parseDouble(String)
     */
    protected final Double getElementAsDouble() throws XMLStreamException {
        final String text = getElementText();
        return (text != null) ? Numerics.valueOf(parseDouble(text)) : null;
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()} as a date,
     * or {@code null} if that value is null or empty.
     *
     * @return the current text element as a date, or {@code null} if empty.
     * @throws XMLStreamException if a text element can not be returned.
     * @throws DateTimeParseException if the text can not be parsed as a date.
     */
    protected final Date getElementAsDate() throws XMLStreamException {
        final String text = getElementText();
        return (text != null) ? StandardDateFormat.toDate(StandardDateFormat.FORMAT.parse(text)) : null;
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()} as a temporal object,
     * or {@code null} if that value is null or empty.
     *
     * @return the current text element as a temporal object, or {@code null} if empty.
     * @throws XMLStreamException if a text element can not be returned.
     * @throws DateTimeParseException if the text can not be parsed as a date.
     */
    protected final Temporal getElementAsTemporal() throws XMLStreamException {
        return StandardDateFormat.parseBest(getElementText());
    }

    /**
     * Returns the current value of {@link XMLStreamReader#getElementText()} as a list of strings,
     * or {@code null} if that value is null or empty.
     *
     * @return the current text element as a list.
     * @throws XMLStreamException if a text element can not be returned.
     */
    protected final List<String> getElementAsList() throws XMLStreamException {
        final String text = getElementText();
        return (text != null) ? Arrays.asList(text.split(" ")) : null;
    }

    /**
     * Parses the given text as a XML floating point number. This method performs the same parsing than
     * {@link Double#valueOf(String)} with the addition of {@code INF} and {@code -INF} values.
     * The following summarizes the special values (note that parsing is case-sensitive):
     *
     * <ul>
     *   <li>{@code NaN}  — a XML value which is also understood natively by {@link Double#valueOf(String)}.</li>
     *   <li>{@code INF}  — a XML value which is processed by this method.</li>
     *   <li>{@code -INF} — a XML value which is processed by this method.</li>
     *   <li>{@code +INF} — illegal XML value, nevertheless processed by this method.</li>
     *   <li>{@code Infinity} — a {@link Double#valueOf(String)} specific value.</li>
     * </ul>
     *
     * <div class="note"><b>Note:</b>
     * this method duplicates {@link javax.xml.bind.DatatypeConverter#parseDouble(String)} work,
     * but avoid synchronization or volatile field cost of {@code DatatypeConverter}.</div>
     *
     * @param  value  the text to parse.
     * @return the floating point value for the given text.
     * @throws NumberFormatException if parsing failed.
     *
     * @see #getElementAsDouble()
     * @see javax.xml.bind.DatatypeConverter#parseDouble(String)
     */
    @SuppressWarnings("fallthrough")
    protected static double parseDouble(final String value) throws NumberFormatException {
        if (!value.endsWith("INF")) {
            return Double.parseDouble(value);
        }
parse:  switch (value.length()) {
            case 4: switch (value.charAt(0)) {
                default:  break parse;
                case '-': return Double.NEGATIVE_INFINITY;
                case '+': // Fall through
            }
            case 3: return Double.POSITIVE_INFINITY;
        }
        throw new NumberFormatException(value);
    }

    /**
     * Parses the given string as a boolean value. This method performs the same parsing than
     * {@link Boolean#parseBoolean(String)} with one extension: the "0" value is considered
     * as {@code false} and the "1" value as {@code true}.
     *
     * <div class="note"><b>Note:</b>
     * this method duplicates {@link javax.xml.bind.DatatypeConverter#parseBoolean(String)} work
     * (except for its behavior in case of invalid value), but avoid synchronization or volatile
     * field cost of {@code DatatypeConverter}.</div>
     *
     * @param value  the string value to parse as a boolean.
     * @return true if the boolean is equal to "true" or "1".
     *
     * @see javax.xml.bind.DatatypeConverter#parseBoolean(String)
     */
    protected static boolean parseBoolean(final String value) {
        if (value.length() == 1) {
            switch (value.charAt(0)) {
                case '0': return false;
                case '1': return true;
            }
        }
        return Boolean.parseBoolean(value);
    }

    /**
     * Delegates to JAXB the unmarshalling of a part of XML document, starting from the current element (inclusive).
     * This method assumes that the reader is on {@link #START_ELEMENT}. After this method invocation, the reader
     * will be on the event <strong>after</strong> {@link #END_ELEMENT}; this implies that the caller will need to
     * invoke {@link XMLStreamReader#getEventType()} instead of {@link XMLStreamReader#next()}.
     *
     * @param  <T>   compile-time value of the {@code type} argument.
     * @param  type  expected type of the object to unmarshal.
     * @return the unmarshalled object, or {@code null} if none.
     * @throws XMLStreamException if the XML stream is closed.
     * @throws JAXBException if an error occurred during unmarshalling.
     * @throws ClassCastException if the unmarshalling result is not of the expected type.
     *
     * @see javax.xml.bind.Unmarshaller#unmarshal(XMLStreamReader, Class)
     */
    protected final <T> T unmarshal(final Class<T> type) throws XMLStreamException, JAXBException {
        Unmarshaller m = unmarshaller;
        if (m == null) {
            m = getMarshallerPool().acquireUnmarshaller();
            for (final Map.Entry<String,?> entry : ((Map<String,?>) owner.configuration).entrySet()) {
                m.setProperty(entry.getKey(), entry.getValue());
            }
        }
        unmarshaller = null;
        final JAXBElement<T> element = m.unmarshal(reader, type);
        unmarshaller = m;                                           // Allow reuse or recycling only on success.
        isNextDone = true;
        return element.getValue();
    }

    /**
     * Closes the input stream and releases any resources used by this XML reader.
     * This reader can not be used anymore after this method has been invoked.
     *
     * @throws XMLStreamException if an error occurred while releasing XML reader resources.
     * @throws IOException if an error occurred while closing the input stream.
     */
    @Override
    public void close() throws Exception {
        final Unmarshaller m = unmarshaller;
        if (m != null) {
            unmarshaller = null;
            getMarshallerPool().recycle(m);
        }
        reader.close();
        super.close();
    }

    /**
     * Invokes {@link #close()} and wraps checked exceptions in a {@link BackingStoreException}.
     * This method is defined for allowing this {@code StaxStreamReader} to be given to
     * {@link java.util.stream.Stream#onClose(Runnable)}.
     */
    @Override
    public final void run() throws BackingStoreException {
        try {
            close();
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new BackingStoreException(e);
        }
    }

    /**
     * Returns an error message for {@link EOFException}.
     * This a convenience method for a frequently-used error.
     *
     * @return a localized error message for end of file error.
     */
    protected final String endOfFile() {
        return errors().getString(Errors.Keys.UnexpectedEndOfFile_1, owner.getDisplayName());
    }

    /**
     * Returns an error message for {@link BackingStoreException}.
     * This a convenience method for {@link #tryAdvance(Consumer)} implementations.
     * The error message will contain the current line and column number if available.
     *
     * @return a localized error message for a file that can not be parsed.
     */
    protected final String canNotParseFile() {
        return IOUtilities.canNotReadFile(owner.getLocale(), owner.getFormatName(), owner.getDisplayName(), reader);
    }

    /**
     * Returns an error message saying that nested elements are not allowed.
     *
     * @param  name  the name of the nested element found.
     * @return a localized error message for forbidden nested element.
     */
    protected final String nestedElement(final String name) {
        return errors().getString(Errors.Keys.NestedElementNotAllowed_1, name);
    }
}
