/*
 * Copyright (c) 1997, 2020 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.impl.parser.state;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Stack;
import java.util.StringTokenizer;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * Runtime Engine for RELAXNGCC execution.
 *
 * This class has the following functionalities:
 *
 * <ol>
 *  <li>Managing a stack of NGCCHandler objects and
 *      switching between them appropriately.
 *
 *  <li>Keep track of all Attributes.
 *
 *  <li>manage mapping between namespace URIs and prefixes.
 *
 *  <li>TODO: provide support for interleaving.
 *  </ol>
 *
 * <p><b>
 *     Auto-generated, do not edit.
 * </b></p>
 * @version $Id: NGCCRuntime.java,v 1.15 2002/09/29 02:55:48 okajima Exp $
 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
 */
public class NGCCRuntime implements ContentHandler, NGCCEventSource {

    public NGCCRuntime() {
        reset();
    }

    /**
     * Sets the root handler, which will be used to parse the
     * root element.
     * <p>
     * This method can be called right after the object is created
     * or the reset method is called. You can't replace the root
     * handler while parsing is in progress.
     * <p>
     * Usually a generated class that corresponds to the {@code <start>}
     * pattern will be used as the root handler, but any NGCCHandler
     * can be a root handler.
     *
     * @exception IllegalStateException
     *      If this method is called but it doesn't satisfy the
     *      pre-condition stated above.
     */
    public void setRootHandler( NGCCHandler rootHandler ) {
        if(currentHandler!=null)
            throw new IllegalStateException();
        currentHandler = rootHandler;
    }


    /**
     * Cleans up all the data structure so that the object can be reused later.
     * Normally, applications do not need to call this method directly,
     *
     * as the runtime resets itself after the endDocument method.
     */
    public void reset() {
        attStack.clear();
        currentAtts = null;
        currentHandler = null;
        indent=0;
        locator = null;
        namespaces.clear();
        needIndent = true;
        redirect = null;
        redirectionDepth = 0;
        text = new StringBuffer();

        // add a dummy attributes at the bottom as a "centinel."
        attStack.push(new AttributesImpl());
    }

    // current content handler can be acccessed via set/getContentHandler.

    private Locator locator;
    public void setDocumentLocator( Locator _loc ) { this.locator=_loc; }
    /**
     * Gets the source location of the current event.
     *
     * <p>
     * One can call this method from RelaxNGCC handlers to access
     * the line number information. Note that to
     */
    public Locator getLocator() { return locator; }


    /** stack of {@link Attributes}. */
    private final Stack attStack = new Stack();
    /** current attributes set. always equal to attStack.peek() */
    private AttributesImpl currentAtts;

    /**
     * Attributes that belong to the current element.
     * <p>
     * It's generally not recommended for applications to use
     * this method. RelaxNGCC internally removes processed attributes,
     * so this doesn't correctly reflect all the attributes an element
     * carries.
     */
    public Attributes getCurrentAttributes() {
        return currentAtts;
    }

    /** accumulated text. */
    private StringBuffer text = new StringBuffer();




    /** The current NGCCHandler. Always equals to handlerStack.peek() */
    private NGCCEventReceiver currentHandler;

    public int replace( NGCCEventReceiver o, NGCCEventReceiver n ) {
        if(o!=currentHandler)
            throw new IllegalStateException();  // bug of RelaxNGCC
        currentHandler = n;

        return 0;   // we only have one thread.
    }

    /**
     * Processes buffered text.
     *
     * This method will be called by the start/endElement event to process
     * buffered text as a text event.
     *
     * <p>
     * Whitespace handling is a tricky business. Consider the following
     * schema fragment:
     *
     * <pre>{@code
     * <element name="foo">
     *   <choice>
     *     <element name="bar"><empty/></element>
     *     <text/>
     *   </choice>
     * </element>
     * }</pre>
     *
     * Assume we hit the following instance:
     * <pre>{@code
     * <foo> <bar/></foo>
     * }</pre>
     *
     * Then this first space needs to be ignored (for otherwise, we will
     * end up treating this space as the match to {@code <text/>} and won't
     * be able to process {@code <bar>}.)
     *
     * Now assume the following instance:
     * <pre>{@code
     * <foo/>
     * }</pre>
     *
     * This time, we need to treat this empty string as a text, for
     * otherwise we won't be able to accept this instance.
     *
     * <p>
     * This is very difficult to solve in general, but one seemingly
     * easy solution is to use the type of next event. If a text is
     * followed by a start tag, it follows from the constraint on
     * RELAX NG that that text must be either whitespaces or a match
     * to {@code <text/>}.
     *
     * <p>
     * On the contrary, if a text is followed by a end tag, then it
     * cannot be whitespace unless the content model can accept empty,
     * in which case sending a text event will be harmlessly ignored
     * by the NGCCHandler.
     *
     * <p>
     * Thus this method take one parameter, which controls the
     * behavior of this method.
     *
     * <p>
     * TODO: according to the constraint of RELAX NG, if characters
     * follow an end tag, then they must be either whitespaces or
     * must match to {@code <text/>}.
     *
     * @param ignorable
     *      True if the buffered character can be ignorabale. False if
     *      it needs to be consumed.
     */
    private void processPendingText(boolean ignorable) throws SAXException {
        if(ignorable && text.toString().trim().length()==0)
            ; // ignore. See the above javadoc comment for the description
        else
            currentHandler.text(text.toString());   // otherwise consume this token

        // truncate StringBuffer, but avoid excessive allocation.
        if(text.length()>1024)  text = new StringBuffer();
        else                    text.setLength(0);
    }

    public void processList( String str ) throws SAXException {
        StringTokenizer t = new StringTokenizer(str, " \t\r\n");
        while(t.hasMoreTokens())
            currentHandler.text(t.nextToken());
    }

    public void startElement(String uri, String localname, String qname, Attributes atts)
            throws SAXException {

        if(redirect!=null) {
            redirect.startElement(uri,localname,qname,atts);
            redirectionDepth++;
        } else {
            processPendingText(true);
            //        System.out.println("startElement:"+localname+"->"+_attrStack.size());
            currentHandler.enterElement(uri, localname, qname, atts);
        }
    }

    /**
     * Called by the generated handler code when an enter element
     * event is consumed.
     *
     * <p>
     * Pushes a new attribute set.
     *
     * <p>
     * Note that attributes are NOT pushed at the startElement method,
     * because the processing of the enterElement event can trigger
     * other attribute events and etc.
     * <p>
     * This method will be called from one of handlers when it truely
     * consumes the enterElement event.
     */
    public void onEnterElementConsumed(
            String uri, String localName, String qname,Attributes atts) throws SAXException {
        attStack.push(currentAtts=new AttributesImpl(atts));
        nsEffectiveStack.push( Integer.valueOf(nsEffectivePtr) );
        nsEffectivePtr = namespaces.size();
    }

    public void onLeaveElementConsumed(String uri, String localName, String qname) throws SAXException {
        attStack.pop();
        if(attStack.isEmpty())
            currentAtts = null;
        else
            currentAtts = (AttributesImpl)attStack.peek();
        nsEffectivePtr = ((Integer)nsEffectiveStack.pop()).intValue();
    }

    public void endElement(String uri, String localname, String qname)
            throws SAXException {

        if(redirect!=null) {
            redirect.endElement(uri,localname,qname);
            redirectionDepth--;

            if(redirectionDepth!=0)
                return;

            // finished redirection.
            for( int i=0; i<namespaces.size(); i+=2 )
                redirect.endPrefixMapping((String)namespaces.get(i));
            redirect.endDocument();

            redirect = null;
            // then process this element normally
        }

        processPendingText(false);

        currentHandler.leaveElement(uri, localname, qname);
//        System.out.println("endElement:"+localname);
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        if(redirect!=null)
            redirect.characters(ch,start,length);
        else
            text.append(ch,start,length);
    }
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        if(redirect!=null)
            redirect.ignorableWhitespace(ch,start,length);
        else
            text.append(ch,start,length);
    }

    public int getAttributeIndex(String uri, String localname) {
        return currentAtts.getIndex(uri, localname);
    }
    public void consumeAttribute(int index) throws SAXException {
        final String uri    = currentAtts.getURI(index);
        final String local  = currentAtts.getLocalName(index);
        final String qname  = currentAtts.getQName(index);
        final String value  = currentAtts.getValue(index);
        currentAtts.removeAttribute(index);

        currentHandler.enterAttribute(uri,local,qname);
        currentHandler.text(value);
        currentHandler.leaveAttribute(uri,local,qname);
    }


    public void startPrefixMapping( String prefix, String uri ) throws SAXException {
        if(redirect!=null)
            redirect.startPrefixMapping(prefix,uri);
        else {
            namespaces.add(prefix);
            namespaces.add(uri);
        }
    }

    public void endPrefixMapping( String prefix ) throws SAXException {
        if(redirect!=null)
            redirect.endPrefixMapping(prefix);
        else {
            namespaces.remove(namespaces.size()-1);
            namespaces.remove(namespaces.size()-1);
        }
    }

    public void skippedEntity( String name ) throws SAXException {
        if(redirect!=null)
            redirect.skippedEntity(name);
    }

    public void processingInstruction( String target, String data ) throws SAXException {
        if(redirect!=null)
            redirect.processingInstruction(target,data);
    }

    /** Impossible token. This value can never be a valid XML name. */
    static final String IMPOSSIBLE = "\u0000";

    public void endDocument() throws SAXException {
        // consume the special "end document" token so that all the handlers
        // currently at the stack will revert to their respective parents.
        //
        // this is necessary to handle a grammar like
        // <start><ref name="X"/></start>
        // <define name="X">
        //   <element name="root"><empty/></element>
        // </define>
        //
        // With this grammar, when the endElement event is consumed, two handlers
        // are on the stack (because a child object won't revert to its parent
        // unless it sees a next event.)

        // pass around an "impossible" token.
        currentHandler.leaveElement(IMPOSSIBLE,IMPOSSIBLE,IMPOSSIBLE);

        reset();
    }
    public void startDocument() {}




//
//
// event dispatching methods
//
//

    public void sendEnterAttribute( int threadId,
                                    String uri, String local, String qname) throws SAXException {

        currentHandler.enterAttribute(uri,local,qname);
    }

    public void sendEnterElement( int threadId,
                                  String uri, String local, String qname, Attributes atts) throws SAXException {

        currentHandler.enterElement(uri,local,qname,atts);
    }

    public void sendLeaveAttribute( int threadId,
                                    String uri, String local, String qname) throws SAXException {

        currentHandler.leaveAttribute(uri,local,qname);
    }

    public void sendLeaveElement( int threadId,
                                  String uri, String local, String qname) throws SAXException {

        currentHandler.leaveElement(uri,local,qname);
    }

    public void sendText(int threadId, String value) throws SAXException {
        currentHandler.text(value);
    }


//
//
// redirection of SAX2 events.
//
//
    /** When redirecting a sub-tree, this value will be non-null. */
    private ContentHandler redirect = null;

    /**
     * Counts the depth of the elements when we are re-directing
     * a sub-tree to another ContentHandler.
     */
    private int redirectionDepth = 0;

    /**
     * This method can be called only from the enterElement handler.
     * The sub-tree rooted at the new element will be redirected
     * to the specified ContentHandler.
     *
     * <p>
     * Currently active NGCCHandler will only receive the leaveElement
     * event of the newly started element.
     *
     * @param   uri,local,qname
     *      Parameters passed to the enter element event. Used to
     *      simulate the startElement event for the new ContentHandler.
     */
    public void redirectSubtree( ContentHandler child,
                                 String uri, String local, String qname ) throws SAXException {

        redirect = child;
        redirect.setDocumentLocator(locator);
        redirect.startDocument();

        // TODO: when a prefix is re-bound to something else,
        // the following code is potentially dangerous. It should be
        // modified to report active bindings only.
        for( int i=0; i<namespaces.size(); i+=2 )
            redirect.startPrefixMapping(
                    (String)namespaces.get(i),
                    (String)namespaces.get(i+1)
            );

        redirect.startElement(uri,local,qname,currentAtts);
        redirectionDepth=1;
    }

//
//
// validation context implementation
//
//
    /** in-scope namespace mapping.
     * namespaces[2n  ] := prefix
     * namespaces[2n+1] := namespace URI */
    private final ArrayList namespaces = new ArrayList();
    /**
     * Index on the namespaces array, which points to
     * the top of the effective bindings. Because of the
     * timing difference between the startPrefixMapping method
     * and the execution of the corresponding actions,
     * this value can be different from {@code namespaces.size()}.
     * <p>
     * For example, consider the following schema:
     * <pre>{@code
     *  <oneOrMore>
     *   <element name="foo"><empty/></element>
     *  </oneOrMore>
     *  code fragment X
     *  <element name="bob"/>
     * }</pre>
     * Code fragment X is executed after we see a startElement event,
     * but at this time the namespaces variable already include new
     * namespace bindings declared on "bob".
     */
    private int nsEffectivePtr=0;

    /**
     * Stack to preserve old nsEffectivePtr values.
     */
    private final Stack nsEffectiveStack = new Stack();

    public String resolveNamespacePrefix( String prefix ) {
        for( int i = nsEffectivePtr-2; i>=0; i-=2 )
            if( namespaces.get(i).equals(prefix) )
                return (String)namespaces.get(i+1);

        // no binding was found.
        if(prefix.equals(""))   return "";  // return the default no-namespace
        if(prefix.equals("xml"))    // pre-defined xml prefix
            return "http://www.w3.org/XML/1998/namespace";
        else    return null;    // prefix undefined
    }


    // error reporting
    protected void unexpectedX(String token) throws SAXException {
        throw new SAXParseException(MessageFormat.format(
                "Unexpected {0} appears at line {1} column {2}",
                new Object[]{
                        token,
                        Integer.valueOf(getLocator().getLineNumber()),
                        Integer.valueOf(getLocator().getColumnNumber()) }),
                getLocator());
    }




    //
//
// trace functions
//
//
    private int indent=0;
    private boolean needIndent=true;
    private void printIndent() {
        for( int i=0; i<indent; i++ )
            System.out.print("  ");
    }
    public void trace( String s ) {
        if(needIndent) {
            needIndent=false;
            printIndent();
        }
        System.out.print(s);
    }
    public void traceln( String s ) {
        trace(s);
        trace("\n");
        needIndent=true;
    }
}
