// 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 com.cloud.bridge.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XSerializer {
    protected final static Logger logger = Logger.getLogger(XSerializer.class);
    
    private static Map<String, Class<?>> rootTypes = new HashMap<String, Class<?>>();
    
    private XSerializerAdapter adapter;
    private boolean flattenCollection;
    private boolean omitNull; 
    
    public XSerializer(XSerializerAdapter adapter) {
    	this.adapter = adapter;
    	adapter.setSerializer(this);
    	
    	// set default serialization options
    	flattenCollection = false;
    	omitNull = false;
    }
    
    public XSerializer(XSerializerAdapter adapter, boolean flattenCollection, boolean omitNull) {
    	this.adapter = adapter;
    	adapter.setSerializer(this);
    	
    	this.flattenCollection = flattenCollection;
    	this.omitNull = omitNull;
    }
    
    public boolean getFlattenCollection() {
    	return flattenCollection;
    }
    
    public void setFlattenCollection(boolean value) {
    	flattenCollection = value;
    }
    
    public boolean flattenField(Field f) {
    	XFlatten flatten = f.getAnnotation(XFlatten.class);
    	if(flatten != null)
    		return flatten.value();
    	return flattenCollection;
    }
    
    public boolean omitNullField(Field f) {
    	XOmitNull omit= f.getAnnotation(XOmitNull.class);
    	if(omit != null)
    		return omit.value();
    	
    	return omitNull;
    }
    
    public boolean getOmitNull() {
    	return omitNull;
    }
    
    public void setOmitNull(boolean value) {
    	omitNull = value;
    }
    
    public static void registerRootType(String elementName, Class<?> clz) {
    	rootTypes.put(elementName, clz);
    }
    
    public XSerializerAdapter getAdapter() {
    	return adapter;
    }
    
    public static Object mapElement(String elementName) {
    	Class<?> clz = rootTypes.get(elementName);
    	if(clz == null) {
    		logger.error("Object class is not registered for root element " + elementName);
    		throw new IllegalArgumentException("Object class is not registered for root element " + elementName);
    	}
    	
    	try {
			return clz.newInstance();
		} catch (InstantiationException e) {
    		logger.error("Unable to instantiate object for root element due to InstantiationException, XML element: " + elementName);
    		throw new IllegalArgumentException("Unable to instantiate object for root element " + elementName);
		} catch (IllegalAccessException e) {
    		logger.error("Unable to instantiate object for root element due to IllegalAccessException, XML element: " + elementName);
    		throw new IllegalArgumentException("Unable to instantiate object for root element due to IllegalAccessException, XML element: " + elementName);
		}
    }
    
    public Object serializeFrom(String xmlString) {
    	try {
			Document doc = XmlHelper.parse(xmlString);
			Node node = XmlHelper.getRootNode(doc);
			if(node == null) {
				logger.error("Invalid XML document, no root element");
				return null;
			}
			
			Object object = mapElement(node.getNodeName());
			if(object == null) {
				logger.error("Unable to map root element. Please remember to use XSerializer.registerRootType() to register the root object type");
				return null;
			}
			
			if(object instanceof XSerializable)
				((XSerializable)object).serializeFrom(this, object, node);
			else
				serializeFrom(object, object.getClass(), node);
			
			return object;
		} catch (IOException e) {
			logger.error("Unable to parse XML input due to " + e.getMessage(), e);
		}
    	return null;
    }
    
    private void serializeFrom(Object object, Class<?> clz, Node node) {
		if(clz.getSuperclass() != null)
			serializeFrom(object, clz.getSuperclass(), node);
		
		Field[] fields = clz.getDeclaredFields();
		for(int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			
			if((f.getModifiers() & Modifier.STATIC) == 0) {
				f.setAccessible(true);

				Class<?> fieldType = f.getType();
				XElement elem = f.getAnnotation(XElement.class);
				if(elem == null)
					continue;
				
				try {
					if(fieldType.isPrimitive()) {
						setPrimitiveField(f, object, XmlHelper.getChildNodeTextContent(node, elem.name()));
					} else if(fieldType.getSuperclass() == Number.class) {
						setNumberField(f, object, XmlHelper.getChildNodeTextContent(node, elem.name()));
					} else if(fieldType == String.class) {
						f.set(object, XmlHelper.getChildNodeTextContent(node, elem.name()));
					} else if(fieldType == Date.class) {
						setDateField(f, object, XmlHelper.getChildNodeTextContent(node, elem.name()));
					} else if(fieldType == Calendar.class) {
						setCalendarField(f, object, XmlHelper.getChildNodeTextContent(node, elem.name()));
					} else if(fieldType.isArray()) {
						if(flattenField(f))
							setArrayField(f, object, node, elem.item(), elem.itemClass());
						else
							setArrayField(f, object, XmlHelper.getChildNode(node, elem.name()), elem.item(), elem.itemClass());
					} else if(Collection.class.isAssignableFrom(fieldType)) {
						if(flattenField(f))
							setCollectionField(f, object, node, elem.item(), elem.itemClass());
						else
							setCollectionField(f, object, XmlHelper.getChildNode(node, elem.name()), elem.item(), elem.itemClass());
					} else {
						Node childNode = XmlHelper.getChildNode(node, elem.name());
						Object fieldObject = f.get(object);
						if(fieldObject == null) {
							try {
								fieldObject = fieldType.newInstance();
							} catch (InstantiationException e) {
								logger.error("Unable to instantiate " + fieldType.getName() + " object, please make sure it has public constructor");
								assert(false);
							}
							f.set(object, fieldObject);
						} 
						serializeFrom(fieldObject, fieldType, childNode);
					}
				} catch(IllegalArgumentException e) {
					logger.error("Unexpected exception " + e.getMessage(), e);
				} catch(IllegalAccessException e) {
					logger.error("Unexpected exception " + e.getMessage(), e);
				}
			}
		}
    }
    
    private void setPrimitiveField(Field f, Object object, String valueContent) 
    	throws IllegalArgumentException, IllegalAccessException {
    	
    	String clzName = f.getType().getName();
		if(clzName.equals("boolean")) {
			if(valueContent != null && valueContent.equalsIgnoreCase("true"))
				f.setBoolean(object, true);
			else
				f.setBoolean(object, false);
		} else if(clzName.equals("byte")) {
			byte value = 0;
			if(valueContent != null)
				value = Byte.parseByte(valueContent);
			f.setByte(object, value);
		} else if(clzName.equals("char")) {
			char value = '\0';
			if(valueContent != null) {
				if(valueContent.charAt(0) == '\'')
					value = valueContent.charAt(1);
				else
					value = valueContent.charAt(0);
			}
			f.setChar(object, value);
		} else if(clzName.equals("short")) {
			short value = 0;
			if(valueContent != null)
				value = Short.parseShort(valueContent);
			f.setShort(object, value);
		} else if(clzName.equals("int")) {
			int value = 0;
			if(valueContent != null)
				value = Integer.parseInt(valueContent);
			f.setInt(object, value);
		} else if(clzName.equals("long")) {
			long value = 0;
			if(valueContent != null)
				value = Long.parseLong(valueContent);
			f.setLong(object, value);
		} else if(clzName.equals("float")) {
			float value = 0;
			if(valueContent != null)
				value = Float.parseFloat(valueContent);
			f.setFloat(object, value);
		} else if(clzName.equals("double")) {
			double value = 0;
			if(valueContent != null)
				value = Double.parseDouble(valueContent);
			f.setDouble(object, value);
		} else {
			logger.error("Assertion failed at setPrimitiveFiled");
			assert(false);
		}
    }
    
    private void setNumberField(Field f, Object object, String valueContent) 
		throws IllegalArgumentException, IllegalAccessException {
    	
    	String clzName = f.getType().getName();
		if(clzName.equals("Byte")) {
			byte value = 0;
			if(valueContent != null)
				value = Byte.parseByte(valueContent);
			f.set(object, new Byte(value));
		} else if(clzName.equals("Short")) {
			short value = 0;
			if(valueContent != null)
				value = Short.parseShort(valueContent);
			f.set(object, new Short(value));
		} else if(clzName.equals("Integer")) {
			int value = 0;
			if(valueContent != null)
				value = Integer.parseInt(valueContent);
			f.set(object, new Integer(value));
		} else if(clzName.equals("Long")) {
			long value = 0;
			if(valueContent != null)
				value = Long.parseLong(valueContent);
			f.set(object, new Long(value));
		} else if(clzName.equals("Float")) {
			float value = 0;
			if(valueContent != null)
				value = Float.parseFloat(valueContent);
			f.set(object, new Float(value));
		} else if(clzName.equals("Double")) {
			double value = 0;
			if(valueContent != null)
				value = Double.parseDouble(valueContent);
			f.setDouble(object, new Double(value));
		} else if(clzName.equals("AtomicInteger")) {
			int value = 0;
			if(valueContent != null)
				value = Integer.parseInt(valueContent);
			f.set(object, new AtomicInteger(value));
		} else if(clzName.equals("AtomicLong")) {
			long value = 0;
			if(valueContent != null)
				value = Long.parseLong(valueContent);
			f.set(object, new AtomicLong(value));
		} else if(clzName.equals("BigInteger")) {
			logger.error("we don't support BigInteger for now");
			assert(false);
		} else if(clzName.equals("BigDecimal")) {
			logger.error("we don't support BigInteger for now");
			assert(false);
		} else {
			logger.error("Assertion failed at setPrimitiveFiled");
			assert(false);
		}
    }
    
    private void setDateField(Field f, Object object, String valueContent) 
		throws IllegalArgumentException, IllegalAccessException {
    	
    	if(valueContent != null) {
    		valueContent = valueContent.replace('T', ' ');
    		valueContent = valueContent.replace('.', '\0');
    		
    		SimpleDateFormat df = DateHelper.getGMTDateFormat("yyyy-MM-dd HH:mm:ss");
    		try {
				Date value = df.parse(valueContent);
				f.set(object, value);
			} catch (ParseException e) {
				logger.error("Unrecognized date/time format " + valueContent);
			}
    	}
    }
    
    private void setCalendarField(Field f, Object object, String valueContent) 
		throws IllegalArgumentException, IllegalAccessException {
    	
    	if(valueContent != null) {
    		valueContent = valueContent.replace('T', ' ');
    		valueContent = valueContent.replace('.', '\0');
    		
    		SimpleDateFormat df = DateHelper.getGMTDateFormat("yyyy-MM-dd HH:mm:ss");
    		try {
				Date value = df.parse(valueContent);
				f.set(object, DateHelper.toCalendar(value));
			} catch (ParseException e) {
				logger.error("Unrecognized date/time format " + valueContent);
			}
    	}
    }

    private void setArrayField(Field f, Object object, Node node, String itemElementName, String itemClass) 
		throws IllegalArgumentException, IllegalAccessException {
    	
    	List<Object> arrayList = new ArrayList<Object>();
    	
    	Class<?> itemClz = null;
    	try {
    		itemClz = this.getClass().forName(itemClass);
    	} catch (ClassNotFoundException e) {
    		logger.error("Unable to find class " + itemClass);
    		return;
    	}
	
    	if(node != null) {
	    	NodeList l = node.getChildNodes();
	    	if(l != null && l.getLength() > 0) {
	    		for(int i = 0; i < l.getLength(); i++) {
	    			try {
	    				Node itemNode = l.item(i);
	    				if(itemNode.getNodeName().equals(itemElementName)) {
	    					Object item = itemClz.newInstance();
	    					serializeFrom(item, itemClz, l.item(i));
	    					arrayList.add(item);
	    				}
	    			} catch (InstantiationException e) {
	    				logger.error("Unable to initiate object instance for class " + itemClass + ", make sure it has public constructor");
	    				break;
	    			}
	    		}
	    	}
    	}
    	
    	Object arrary = Array.newInstance(f.getType().getComponentType(), arrayList.size());
    	arrayList.toArray((Object[])arrary);
    	f.set(object, arrary);
    }
    
    private void setCollectionField(Field f, Object object, Node node, String itemElementName, String itemClass) 
    	throws IllegalArgumentException, IllegalAccessException {
    	Object fieldObject = f.get(object);
    	
    	if(fieldObject == null) {
    		logger.error("Please initialize collection field " + f.getName() + " in class " + object.getClass().getName() + "'s constructor");
    		return;
    	}
    	
    	Class<?> itemClz = null;
    	try {
			itemClz = this.getClass().forName(itemClass);
		} catch (ClassNotFoundException e) {
    		logger.error("Unable to find class " + itemClass);
    		return;
		}
		
		NodeList l = node.getChildNodes();
		if(l != null && l.getLength() > 0) {
			for(int i = 0; i < l.getLength(); i++) {
				try {
					Node itemNode = l.item(i);
					if(itemNode.getNodeName().equals(itemElementName)) {
						Object item = itemClz.newInstance();
						serializeFrom(item, itemClz, l.item(i));
						((Collection)fieldObject).add(item);
					}
				} catch (InstantiationException e) {
		    		logger.error("Unable to initiate object instance for class " + itemClass + ", make sure it has public constructor");
		    		break;
				}
			}
		}
    }
    
	public void serializeTo(Object obj, String startElement, String namespace, int indentLevel, PrintWriter writer) {
		if(startElement != null) {
			adapter.beginElement(startElement, namespace, indentLevel, writer);
			indentLevel++;
		}
		
		if(obj instanceof XSerializable) {
			((XSerializable)obj).serializeTo(this, indentLevel, writer);
		} else {
			Class<?> clz = obj.getClass();
			serializeTo(obj, clz, indentLevel, writer);
		}
		
		if(startElement != null) {
			indentLevel--;
			adapter.endElement(startElement, indentLevel, writer);
		}
	}
	
	public String serializeTo(Object obj, String startElement, String namespace, int indentLevel) {
		StringWriter writer = new StringWriter();
		serializeTo(obj, startElement, namespace, indentLevel, new PrintWriter(writer));
		return writer.toString();
	}
	
	private void serializeTo(Object obj, Class<?> clz, int indentLevel, PrintWriter writer) {
		if(clz.getSuperclass() != null)
			serializeTo(obj, clz.getSuperclass(), indentLevel, writer);
		
		Field[] fields = clz.getDeclaredFields();
		for(int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			
			if((f.getModifiers() & Modifier.STATIC) == 0) {
				f.setAccessible(true);

				Class<?> fieldType = f.getType();
				XElement elem = f.getAnnotation(XElement.class);
				if(elem == null)
					continue;
				
				Object fieldValue = null;
				try {
					fieldValue = f.get(obj);
				} catch (IllegalArgumentException e) {
					logger.error("Unexpected exception " + e.getMessage(), e);
				} catch (IllegalAccessException e) {
					logger.error("Unexpected exception " + e.getMessage(), e);
				}
				
				adapter.writeElement(elem.name(), elem.item(), fieldValue, f, indentLevel, writer);
				if(i < fields.length - 1) {
					Field next = fields[i + 1];
					if((next.getModifiers() & Modifier.STATIC) == 0 && next.getAnnotation(XElement.class) != null) {
						adapter.writeSeparator(indentLevel, writer);
					}
				}
			}
		}
	}
	
	public boolean isComposite(Class<?> clz) {
		if(clz.isPrimitive() || clz.getSuperclass() == Number.class ||
			clz == String.class || clz == Date.class || clz == Calendar.class) {
			return false;
		}
		return true;
	}
}
