/*
 * 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.camel.management.mbean;

import java.io.InputStream;
import java.util.Stack;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import org.apache.camel.CamelContext;
import org.apache.camel.api.management.ManagedCamelContext;
import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
import org.apache.camel.api.management.mbean.ManagedRouteMBean;

/**
 * An XML parser that uses SAX to enrich route stats in the route dump.
 * <p/>
 * The coverage details:
 * <ul>
 *     <li>exchangesTotal - Total number of exchanges</li>
 *     <li>totalProcessingTime - Total processing time in millis</li>
 * </ul>
 * Is included as attributes on the route nodes.
 */
public final class RouteCoverageXmlParser {

    private RouteCoverageXmlParser() {
    }

    /**
     * Parses the XML.
     *
     * @param camelContext the CamelContext
     * @param is           the XML content as an input stream
     * @return the DOM model of the routes with coverage information stored as attributes
     * @throws Exception is thrown if error parsing
     */
    public static Document parseXml(final CamelContext camelContext, final InputStream is) throws Exception {
        final SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
        final SAXParser parser = factory.newSAXParser();
        final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        docBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
        final DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
        final Document doc = docBuilder.newDocument();

        final Stack<Element> elementStack = new Stack<>();
        final StringBuilder textBuffer = new StringBuilder();
        final DefaultHandler handler = new DefaultHandler() {

            @Override
            public void setDocumentLocator(final Locator locator) {
                // noop
            }

            @Override
            public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException {
                addTextIfNeeded();

                final Element el = doc.createElement(qName);
                // add other elements
                for (int i = 0; i < attributes.getLength(); i++) {
                    el.setAttribute(attributes.getQName(i), attributes.getValue(i));
                }

                String id = el.getAttribute("id");
                if (id != null) {
                    try {
                        if ("route".equals(qName)) {
                            ManagedRouteMBean route = camelContext.getExtension(ManagedCamelContext.class).getManagedRoute(id);
                            if (route != null) {
                                long total = route.getExchangesTotal();
                                el.setAttribute("exchangesTotal", "" + total);
                                long totalTime = route.getTotalProcessingTime();
                                el.setAttribute("totalProcessingTime", "" + totalTime);
                            }
                        } else if ("from".equals(qName)) {
                            // grab statistics from the parent route as from would be the same
                            Element parent = elementStack.peek();
                            if (parent != null) {
                                String routeId = parent.getAttribute("id");
                                ManagedRouteMBean route = camelContext.getExtension(ManagedCamelContext.class).getManagedRoute(routeId);
                                if (route != null) {
                                    long total = route.getExchangesTotal();
                                    el.setAttribute("exchangesTotal", "" + total);
                                    long totalTime = route.getTotalProcessingTime();
                                    el.setAttribute("totalProcessingTime", "" + totalTime);
                                    // from is index-0
                                    el.setAttribute("index", "0");
                                }
                            }
                        } else {
                            ManagedProcessorMBean processor = camelContext.getExtension(ManagedCamelContext.class).getManagedProcessor(id);
                            if (processor != null) {
                                long total = processor.getExchangesTotal();
                                el.setAttribute("exchangesTotal", "" + total);
                                long totalTime = processor.getTotalProcessingTime();
                                el.setAttribute("totalProcessingTime", "" + totalTime);
                                int index = processor.getIndex();
                                el.setAttribute("index", "" + index);
                            }
                        }
                    } catch (Exception e) {
                        // ignore
                    }
                }

                // we do not want customId in output of the EIPs
                if (!"route".equals(qName)) {
                    el.removeAttribute("customId");
                }

                elementStack.push(el);
            }

            @Override
            public void endElement(final String uri, final String localName, final String qName) {
                addTextIfNeeded();
                final Element closedEl = elementStack.pop();
                if (elementStack.isEmpty()) {
                    // is this the root element?
                    doc.appendChild(closedEl);
                } else {
                    final Element parentEl = elementStack.peek();
                    parentEl.appendChild(closedEl);
                }
            }

            @Override
            public void characters(final char[] ch, final int start, final int length) throws SAXException {
                textBuffer.append(ch, start, length);
            }

            /**
             * outputs text accumulated under the current node
             */
            private void addTextIfNeeded() {
                if (textBuffer.length() > 0) {
                    final Element el = elementStack.peek();
                    final Node textNode = doc.createTextNode(textBuffer.toString());
                    el.appendChild(textNode);
                    textBuffer.delete(0, textBuffer.length());
                }
            }
        };
        parser.parse(is, handler);

        return doc;
    }
}
