/*******************************************************************************
 * 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.ofbiz.entity.serialize;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.WeakHashMap;

import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilObject;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericPK;
import org.apache.ofbiz.entity.GenericValue;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * XmlSerializer class. This class is deprecated - new code should use the
 * Java object marshalling/unmarshalling methods in <code>UtilXml.java</code>.
 *
 */
public class XmlSerializer {
    public static final String module = XmlSerializer.class.getName();

    private static WeakReference<DateFormat> simpleDateFormatter;

    public static String serialize(Object object) throws SerializeException, FileNotFoundException, IOException {
        Document document = UtilXml.makeEmptyXmlDocument("ofbiz-ser");
        Element rootElement = document.getDocumentElement();

        rootElement.appendChild(serializeSingle(object, document));
        return UtilXml.writeXmlDocument(document);
    }

    /** Deserialize a Java object from an XML string. <p>This method should be used with caution.
     * If the XML string contains a serialized <code>GenericValue</code> or <code>GenericPK</code>
     * then it is possible to unintentionally corrupt the database.</p>
     * 
     * @param content the content
     * @param delegator the delegator
     * @return return a deserialized object from XML string
     * @throws SerializeException
     * @throws SAXException
     * @throws ParserConfigurationException
     * @throws IOException
     */
    public static Object deserialize(String content, Delegator delegator)
        throws SerializeException, SAXException, ParserConfigurationException, IOException {
        // readXmlDocument with false second parameter to disable validation
        Document document = UtilXml.readXmlDocument(content, false);
        if (document != null) {
            if (!"ofbiz-ser".equals(document.getDocumentElement().getTagName())) {
                return UtilXml.fromXml(content);
            }
            return deserialize(document, delegator);
        } else {
            Debug.logWarning("Serialized document came back null", module);
            return null;
        }
    }

    /** Deserialize a Java object from a DOM <code>Document</code>.
     * <p>This method should be used with caution. If the DOM <code>Document</code>
     * contains a serialized <code>GenericValue</code> or <code>GenericPK</code>
     * then it is possible to unintentionally corrupt the database.</p>
     * 
     * @param document the document
     * @param delegator the delegator
     * @return returns a deserialized object from a DOM document
     * @throws SerializeException
     */
    public static Object deserialize(Document document, Delegator delegator) throws SerializeException {
        Element rootElement = document.getDocumentElement();
        // find the first element below the root element, that should be the object
        Node curChild = rootElement.getFirstChild();
        while (curChild != null && curChild.getNodeType() != Node.ELEMENT_NODE) {
            curChild = curChild.getNextSibling();
        }
        if (curChild == null) {
            return null;
        }
        return deserializeSingle((Element) curChild, delegator);
    }

    public static Element serializeSingle(Object object, Document document) throws SerializeException {
        if (document == null) return null;

        if (object == null) return makeElement("null", object, document);

        // - Standard Objects -
        if (object instanceof String) {
            return makeElement("std-String", object, document);
        } else if (object instanceof Integer) {
            return makeElement("std-Integer", object, document);
        } else if (object instanceof Long) {
            return makeElement("std-Long", object, document);
        } else if (object instanceof Float) {
            return makeElement("std-Float", object, document);
        } else if (object instanceof Double) {
            return makeElement("std-Double", object, document);
        } else if (object instanceof Boolean) {
            return makeElement("std-Boolean", object, document);
        } else if (object instanceof Locale) {
            return makeElement("std-Locale", object, document);
        } else if (object instanceof BigDecimal) {
            String stringValue = ((BigDecimal) object).setScale(10, BigDecimal.ROUND_HALF_UP).toString();            
            return makeElement("std-BigDecimal", stringValue, document);
            // - SQL Objects -
        } else if (object instanceof java.sql.Timestamp) {
            String stringValue = object.toString().replace(' ', 'T');
            return makeElement("sql-Timestamp", stringValue, document);
        } else if (object instanceof java.sql.Date) {
            return makeElement("sql-Date", object, document);
        } else if (object instanceof java.sql.Time) {
            return makeElement("sql-Time", object, document);
        } else if (object instanceof java.util.Date) {
            // NOTE: make sure this is AFTER the java.sql date/time objects since they inherit from java.util.Date
            DateFormat formatter = getDateFormat();
            String stringValue = null;

            synchronized (formatter) {
                stringValue = formatter.format((java.util.Date) object);
            }
            return makeElement("std-Date", stringValue, document);
            // return makeElement("std-Date", object, document);
        } else if (object instanceof Collection<?>) {
            // - Collections -
            String elementName = null;

            // these ARE order sensitive; for instance Stack extends Vector, so if Vector were first we would lose the stack part
            if (object instanceof ArrayList<?>) {
                elementName = "col-ArrayList";
            } else if (object instanceof LinkedList<?>) {
                elementName = "col-LinkedList";
            } else if (object instanceof Stack<?>) {
                elementName = "col-Stack";
            } else if (object instanceof Vector<?>) {
                elementName = "col-Vector";
            } else if (object instanceof TreeSet<?>) {
                elementName = "col-TreeSet";
            } else if (object instanceof HashSet<?>) {
                elementName = "col-HashSet";
            } else {
                // no specific type found, do general Collection, will deserialize as LinkedList
                elementName = "col-Collection";
            }

            // if (elementName == null) return serializeCustom(object, document);

            Collection<?> value = UtilGenerics.cast(object);
            Element element = document.createElement(elementName);
            Iterator<?> iter = value.iterator();

            while (iter.hasNext()) {
                element.appendChild(serializeSingle(iter.next(), document));
            }
            return element;
        } else if (object instanceof GenericPK) {
            // Do GenericEntity objects as a special case, use std XML import/export routines
            GenericPK value = (GenericPK) object;

            return value.makeXmlElement(document, "eepk-");
        } else if (object instanceof GenericValue) {
            GenericValue value = (GenericValue) object;

            return value.makeXmlElement(document, "eeval-");
        } else if (object instanceof Map<?, ?>) {
            // - Maps -
            String elementName = null;

            // these ARE order sensitive; for instance Properties extends Hashtable, so if Hashtable were first we would lose the Properties part
            if (object instanceof HashMap<?, ?>) {
                elementName = "map-HashMap";
            } else if (object instanceof Properties) {
                elementName = "map-Properties";
            } else if (object instanceof Hashtable<?, ?>) {
                elementName = "map-Hashtable";
            } else if (object instanceof WeakHashMap<?, ?>) {
                elementName = "map-WeakHashMap";
            } else if (object instanceof TreeMap<?, ?>) {
                elementName = "map-TreeMap";
            } else {
                // serialize as a simple Map implementation if nothing else applies, these will deserialize as a HashMap
                elementName = "map-Map";
            }

            Element element = document.createElement(elementName);
            Map<?,?> value = UtilGenerics.cast(object);
            Iterator<Map.Entry<?, ?>> iter = UtilGenerics.cast(value.entrySet().iterator());

            while (iter.hasNext()) {
                Map.Entry<?,?> entry = iter.next();

                Element entryElement = document.createElement("map-Entry");

                element.appendChild(entryElement);

                Element key = document.createElement("map-Key");

                entryElement.appendChild(key);
                key.appendChild(serializeSingle(entry.getKey(), document));
                Element mapValue = document.createElement("map-Value");

                entryElement.appendChild(mapValue);
                mapValue.appendChild(serializeSingle(entry.getValue(), document));
            }
            return element;
        }

        return serializeCustom(object, document);
    }

    public static Element serializeCustom(Object object, Document document) throws SerializeException {
        if (object instanceof Serializable) {
            byte[] objBytes = UtilObject.getBytes(object);
            if (objBytes == null) {
                throw new SerializeException("Unable to serialize object; null byte array returned");
            } else {
                String byteHex = StringUtil.toHexString(objBytes);
                Element element = document.createElement("cus-obj");
                // this is hex encoded so does not need to be in a CDATA block
                element.appendChild(document.createTextNode(byteHex));
                return element;
            }
        } else {
            throw new SerializeException("Cannot serialize object of class " + object.getClass().getName());
        }
    }

    public static Element makeElement(String elementName, Object value, Document document) {
        if (value == null) {
            Element element = document.createElement("null");
            element.setAttribute("xsi:nil", "true");
            // I tried to put the schema in the envelope header (in createAndSendSOAPResponse) 
            // resEnv.declareNamespace("http://www.w3.org/2001/XMLSchema-instance", null); 
            // But it gets prefixed and that does not work. So adding in each instance
            element.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
            return element;
        }
        Element element = document.createElement(elementName);

        element.setAttribute("value", value.toString());
        return element;
    }

    public static Object deserializeSingle(Element element, Delegator delegator) throws SerializeException {
        String tagName = element.getLocalName();

        if (tagName.equals("null")) return null;

        if (tagName.startsWith("std-")) {
            // - Standard Objects -
            if ("std-String".equals(tagName)) {
                return element.getAttribute("value");
            } else if ("std-Integer".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return Integer.valueOf(valStr);
            } else if ("std-Long".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return Long.valueOf(valStr);
            } else if ("std-Float".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return Float.valueOf(valStr);
            } else if ("std-Double".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return Double.valueOf(valStr);
            } else if ("std-BigDecimal".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return new BigDecimal(valStr);
            } else if ("std-Boolean".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return Boolean.valueOf(valStr);
            } else if ("std-Locale".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return UtilMisc.parseLocale(valStr);
            } else if ("std-Date".equals(tagName)) {
                String valStr = element.getAttribute("value");
                DateFormat formatter = getDateFormat();
                java.util.Date value = null;

                try {
                    synchronized (formatter) {
                        value = formatter.parse(valStr);
                    }
                } catch (ParseException e) {
                    throw new SerializeException("Could not parse date String: " + valStr, e);
                }
                return value;
            }
        } else if (tagName.startsWith("sql-")) {
            // - SQL Objects -
            if ("sql-Timestamp".equals(tagName)) {
                String valStr = element.getAttribute("value");
                /*
                 * sql-Timestamp is defined as xsd:dateTime in ModelService.getTypes(),
                 * so try to parse the value as xsd:dateTime first.
                 * Fallback is java.sql.Timestamp because it has been this way all the time.
                 */
                try {
                    Calendar cal = DatatypeConverter.parseDate(valStr);
                    return new java.sql.Timestamp(cal.getTimeInMillis());
                }
                catch (Exception e) {
                    Debug.logWarning("sql-Timestamp does not conform to XML Schema definition, try java.sql.Timestamp format", module);
                    return java.sql.Timestamp.valueOf(valStr);
                }
            } else if ("sql-Date".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return java.sql.Date.valueOf(valStr);
            } else if ("sql-Time".equals(tagName)) {
                String valStr = element.getAttribute("value");
                return java.sql.Time.valueOf(valStr);
            }
        } else if (tagName.startsWith("col-")) {
            // - Collections -
            Collection<Object> value = null;

            if ("col-ArrayList".equals(tagName)) {
                value = new ArrayList<Object>();
            } else if ("col-LinkedList".equals(tagName)) {
                value = new LinkedList<Object>();
            } else if ("col-Stack".equals(tagName)) {
                value = new Stack<Object>();
            } else if ("col-Vector".equals(tagName)) {
                value = new Vector<Object>();
            } else if ("col-TreeSet".equals(tagName)) {
                value = new TreeSet<Object>();
            } else if ("col-HashSet".equals(tagName)) {
                value = new HashSet<Object>();
            } else if ("col-Collection".equals(tagName)) {
                value = new LinkedList<Object>();
            }

            if (value == null) {
                return deserializeCustom(element);
            } else {
                Node curChild = element.getFirstChild();

                while (curChild != null) {
                    if (curChild.getNodeType() == Node.ELEMENT_NODE) {
                        value.add(deserializeSingle((Element) curChild, delegator));
                    }
                    curChild = curChild.getNextSibling();
                }
                return value;
            }
        } else if (tagName.startsWith("map-")) {
            // - Maps -
            Map<Object, Object> value = null;

            if ("map-HashMap".equals(tagName)) {
                value = new HashMap<Object, Object>();
            } else if ("map-Properties".equals(tagName)) {
                value = new Properties();
            } else if ("map-Hashtable".equals(tagName)) {
                value = new Hashtable<Object, Object>();
            } else if ("map-WeakHashMap".equals(tagName)) {
                value = new WeakHashMap<Object, Object>();
            } else if ("map-TreeMap".equals(tagName)) {
                value = new TreeMap<Object, Object>();
            } else if ("map-Map".equals(tagName)) {
                value = new HashMap<Object, Object>();
            }

            if (value == null) {
                return deserializeCustom(element);
            } else {
                Node curChild = element.getFirstChild();

                while (curChild != null) {
                    if (curChild.getNodeType() == Node.ELEMENT_NODE) {
                        Element curElement = (Element) curChild;

                        if ("map-Entry".equals(curElement.getLocalName())) {

                            Element mapKeyElement = UtilXml.firstChildElement(curElement, "map-Key");
                            Element keyElement = null;
                            Node tempNode = mapKeyElement.getFirstChild();

                            while (tempNode != null) {
                                if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
                                    keyElement = (Element) tempNode;
                                    break;
                                }
                                tempNode = tempNode.getNextSibling();
                            }
                            if (keyElement == null) throw new SerializeException("Could not find an element under the map-Key");

                            Element mapValueElement = UtilXml.firstChildElement(curElement, "map-Value");
                            Element valueElement = null;

                            tempNode = mapValueElement.getFirstChild();
                            while (tempNode != null) {
                                if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
                                    valueElement = (Element) tempNode;
                                    break;
                                }
                                tempNode = tempNode.getNextSibling();
                            }
                            if (valueElement == null) throw new SerializeException("Could not find an element under the map-Value");

                            value.put(deserializeSingle(keyElement, delegator), deserializeSingle(valueElement, delegator));
                        }
                    }
                    curChild = curChild.getNextSibling();
                }
                return value;
            }
        } else if (tagName.startsWith("eepk-")) {
            return delegator.makePK(element);
        } else if (tagName.startsWith("eeval-")) {
            return delegator.makeValue(element);
        }

        return deserializeCustom(element);
    }

    public static Object deserializeCustom(Element element) throws SerializeException {
        String tagName = element.getLocalName();
        if ("cus-obj".equals(tagName)) {
            String value = UtilXml.elementValue(element);
            if (value != null) {
                byte[] valueBytes = StringUtil.fromHexString(value);
                if (valueBytes != null) {
                    Object obj = UtilObject.getObject(valueBytes);
                    if (obj != null) {
                        return obj;
                    }
                }
            }
            throw new SerializeException("Problem deserializing object from byte array + " + element.getLocalName());
        } else {
            throw new SerializeException("Cannot deserialize element named " + element.getLocalName());
        }
    }

    /**
     * Returns the DateFormat used to serialize and deserialize <code>java.util.Date</code> objects.
     * This format is NOT used to format any of the java.sql subtypes of java.util.Date.
     * A <code>WeakReference</code> is used to maintain a reference to the DateFormat object
     * so that it can be created and garbage collected as needed.
     *
     * @return the DateFormat used to serialize and deserialize <code>java.util.Date</code> objects.
     */
    private static DateFormat getDateFormat() {
        DateFormat formatter = null;

        if (simpleDateFormatter != null) {
            formatter = simpleDateFormatter.get();
        }
        if (formatter == null) {
            formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
            simpleDateFormatter = new WeakReference<DateFormat>(formatter);
        }
        return formatter;
    }
}
