/*
 * Copyright (C) 2011 Citrix Systems, Inc.  All rights reserved.
 * 
 * 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 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;

/**
 * @author Kelven Yang
 */
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;
	}
}
