/*
 * Copyright  2003-2004 The Apache Software Foundation.
 *
 *  Licensed 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.ws.security.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;

/**
 * The abstraction this class provides is a push down stack of variable
 * length frames of prefix to namespace mappings.  Used for keeping track
 * of what namespaces are active at any given point as an XML document is
 * traversed or produced.
 * <p/>
 * From a performance point of view, this data will both be modified frequently
 * (at a minimum, there will be one push and pop per XML element processed),
 * and scanned frequently (many of the "good" mappings will be at the bottom
 * of the stack).  The one saving grace is that the expected maximum
 * cardinalities of the number of frames and the number of total mappings
 * is only in the dozens, representing the nesting depth of an XML document
 * and the number of active namespaces at any point in the processing.
 * <p/>
 * Accordingly, this stack is implemented as a single array, will null
 * values used to indicate frame boundaries.
 *
 * @author James Snell
 * @author Glen Daniels (gdaniels@apache.org)
 * @author Sam Ruby (rubys@us.ibm.com)
 */
public class NSStack {
    protected static Log log =
            LogFactory.getLog(NSStack.class.getName());

    private Mapping[] stack;
    private int top = 0;
    private int iterator = 0;
    private int currentDefaultNS = -1;
    // invariant member variable to track low-level logging requirements
    // we cache this once per instance lifecycle to avoid repeated lookups
    // in heavily used code.
    private final boolean traceEnabled = log.isTraceEnabled();

    public NSStack() {
        stack = new Mapping[32];
        stack[0] = null;
    }

    /**
     * Create a new frame at the top of the stack.
     */
    public void push() {
        top++;
        if (top >= stack.length) {
            Mapping newstack[] = new Mapping[stack.length * 2];
            System.arraycopy(stack, 0, newstack, 0, stack.length);
            stack = newstack;
        }
        if (traceEnabled)
            log.trace("NSPush (" + stack.length + ")");
        stack[top] = null;
    }

    /**
     * Remove the top frame from the stack.
     */
    public void pop() {
        clearFrame();
        top--;

        // If we've moved below the current default NS, figure out the new
        // default (if any)
        if (top < currentDefaultNS) {
            // Reset the currentDefaultNS to ignore the frame just removed.
            currentDefaultNS = top;
            while (currentDefaultNS > 0) {
                if (stack[currentDefaultNS] != null &&
                        stack[currentDefaultNS].getPrefix().length() == 0)
                    break;
                currentDefaultNS--;
            }
        }
        if (top == 0) {
            if (traceEnabled)
                log.trace("NSPop (empty)");
            return;
        }
        if (traceEnabled) {
            log.trace("NSPop (" + stack.length + ")");
        }
    }

    /**
     * Return a copy of the current frame.  Returns null if none are present.
     */
    public ArrayList cloneFrame() {
        if (stack[top] == null) return null;
        ArrayList clone = new ArrayList();
        for (Mapping map = topOfFrame(); map != null; map = next()) {
            clone.add(map);
        }
        return clone;
    }

    /**
     * Remove all mappings from the current frame.
     */
    private void clearFrame() {
        while (stack[top] != null) top--;
    }

    /**
     * Reset the embedded iterator in this class to the top of the current
     * (i.e., last) frame.  Note that this is not threadsafe, nor does it
     * provide multiple iterators, so don't use this recursively.  Nor
     * should you modify the stack while iterating over it.
     */
    public Mapping topOfFrame() {
        iterator = top;
        while (stack[iterator] != null) iterator--;
        iterator++;
        return next();
    }

    /**
     * Return the next namespace mapping in the top frame.
     */
    public Mapping next() {
        if (iterator > top) {
            return null;
        } else {
            return stack[iterator++];
        }
    }

    /**
     * Add a mapping for a namespaceURI to the specified prefix to the top
     * frame in the stack.  If the prefix is already mapped in that frame,
     * remap it to the (possibly different) namespaceURI.
     */
    public void add(String namespaceURI, String prefix) {
        int idx = top;
        try {
            // Replace duplicate prefixes (last wins - this could also fault)
            for (int cursor = top; stack[cursor] != null; cursor--) {
                if (stack[cursor].getPrefix().equals(prefix)) {
                    stack[cursor].setNamespaceURI(namespaceURI);
                    idx = cursor;
                    return;
                }
            }
            push();
            stack[top] = new Mapping(namespaceURI, prefix);
            idx = top;
        } finally {
            // If this is the default namespace, note the new in-scope
            // default is here.
            if (prefix.length() == 0) {
                currentDefaultNS = idx;
            }
        }
    }

    /**
     * Return an active prefix for the given namespaceURI.  NOTE : This
     * may return null even if the namespaceURI was actually mapped further
     * up the stack IF the prefix which was used has been repeated further
     * down the stack.  I.e.:
     * <p/>
     * <pre:outer xmlns:pre="namespace">
     * <pre:inner xmlns:pre="otherNamespace">
     * *here's where we're looking*
     * </pre:inner>
     * </pre:outer>
     * <p/>
     * If we look for a prefix for "namespace" at the indicated spot, we won't
     * find one because "pre" is actually mapped to "otherNamespace"
     */
    public String getPrefix(String namespaceURI, boolean noDefault) {
        if ((namespaceURI == null) || (namespaceURI.equals("")))
            return null;
        int hash = namespaceURI.hashCode();

        // If defaults are OK, and the given NS is the current default,
        // return "" as the prefix to favor defaults where possible.
        if (!noDefault && currentDefaultNS > 0 && stack[currentDefaultNS] != null &&
                namespaceURI.equals(stack[currentDefaultNS].getNamespaceURI()))
            return "";
        for (int cursor = top; cursor > 0; cursor--) {
            Mapping map = stack[cursor];
            if (map == null) continue;
            if (map.getNamespaceHash() == hash &&
                    map.getNamespaceURI().equals(namespaceURI)) {
                String possiblePrefix = map.getPrefix();
                if (noDefault && possiblePrefix.length() == 0) continue;

                // now make sure that this is the first occurance of this 
                // particular prefix
                int ppHash = possiblePrefix.hashCode();
                for (int cursor2 = top; true; cursor2--) {
                    if (cursor2 == cursor) return possiblePrefix;
                    map = stack[cursor2];
                    if (map == null) continue;
                    if (ppHash == map.getPrefixHash() &&
                            possiblePrefix.equals(map.getPrefix()))
                        break;
                }
            }
        }
        return null;
    }

    /**
     * Return an active prefix for the given namespaceURI, including
     * the default prefix ("").
     */
    public String getPrefix(String namespaceURI) {
        return getPrefix(namespaceURI, false);
    }

    /**
     * Given a prefix, return the associated namespace (if any).
     */
    public String getNamespaceURI(String prefix) {
        if (prefix == null)
            prefix = "";
        int hash = prefix.hashCode();
        for (int cursor = top; cursor > 0; cursor--) {
            Mapping map = stack[cursor];
            if (map == null) continue;
            if (map.getPrefixHash() == hash && map.getPrefix().equals(prefix))
                return map.getNamespaceURI();
        }
        return null;
    }

    /**
     * Produce a trace dump of the entire stack, starting from the top and
     * including frame markers.
     */
    public void dump(String dumpPrefix) {
        for (int cursor = top; cursor > 0; cursor--) {
            Mapping map = stack[cursor];
            if (map == null) {
                log.trace(dumpPrefix + "stackFrame00");
            } else {
                log.trace(dumpPrefix + map.getNamespaceURI() + " -> " + map.getPrefix());
            }
        }
    }
}
