/*
 *  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.synapse.config.xml;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.message.processors.MessageProcessor;
import org.apache.synapse.util.xpath.SynapseXPath;

import javax.xml.namespace.QName;
import java.util.Iterator;


/**
 * Create an instance of the given Message processor, and sets properties on it.
 * <p/>
 * &lt;messageProcessor name="string" class="classname" messageStore = "string" &gt;
 * &lt;parameter name="string"&gt"string" &lt;parameter&gt;
 * &lt;parameter name="string"&gt"string" &lt;parameter&gt;
 * &lt;parameter name="string"&gt"string" &lt;parameter&gt;
 * &lt;parameter name="string" expression="string"&gt;
 * .
 * .
 * &lt;/messageProcessor&gt;
 */
public class MessageProcessorSerializer {

    private static final Log log = LogFactory.getLog(MessageProcessorSerializer.class);

    protected static final OMFactory fac = OMAbstractFactory.getOMFactory();
    protected static final OMNamespace synNS = SynapseConstants.SYNAPSE_OMNAMESPACE;
    protected static final OMNamespace nullNS = fac.createOMNamespace(
            XMLConfigConstants.NULL_NAMESPACE, "");


    /**
     * Serialize a give Message processor instance to XML configuration
     *
     * @param parent    parent configuration
     * @param processor message processor instance
     * @return created XML configuration
     */
    public static OMElement serializeMessageProcessor(OMElement parent,
                                                      MessageProcessor processor) {
        OMElement processorElem = fac.createOMElement("messageProcessor", synNS);
        if (processor != null) {
            processorElem.addAttribute(fac.createOMAttribute("class", nullNS,
                                                             processor.getClass().getName()));
        } else {
            handleException("Invalid processor. Provider is required");
        }

        if (processor.getName() != null) {
            processorElem.addAttribute(fac.createOMAttribute("name", nullNS, processor.getName()));
        } else {
            handleException("Message store Name not specified");
        }

        if (processor.getMessageStoreName() != null) {
            processorElem.addAttribute(fac.createOMAttribute(
                    "messageStore", nullNS, processor.getMessageStoreName()));
        }

        if (processor.getParameters() != null) {
            Iterator iterator = processor.getParameters().keySet().iterator();
            while (iterator.hasNext()) {
                String name = (String) iterator.next();
                Object object = processor.getParameters().get(name);
                OMElement property = fac.createOMElement("parameter", synNS);
                property.addAttribute(fac.createOMAttribute(
                        "name", nullNS, name));

                if (object instanceof String) {
                    String value = (String) object;
                    property.setText(value.trim());

                } else if (object instanceof SynapseXPath) {
                    SynapseXPath expression = (SynapseXPath) object;
                    SynapseXPathSerializer.serializeXPath(expression,property,"expression");

                }

                processorElem.addChild(property);

            }
        }


        if (getSerializedDescription(processor) != null) {
            processorElem.addChild(getSerializedDescription(processor));
        }

        if (parent != null) {
            parent.addChild(processorElem);
        }
        return processorElem;
    }

    private static void handleException(String msg) {
        log.error(msg);
        throw new SynapseException(msg);
    }

    private static OMElement getSerializedDescription(MessageProcessor processor) {
        OMElement descriptionElem = fac.createOMElement(
                new QName(SynapseConstants.SYNAPSE_NAMESPACE, "description"));

        if (processor.getDescription() != null) {
            descriptionElem.setText(processor.getDescription());
            return descriptionElem;
        } else {
            return null;
        }
    }

}
