package org.apache.ode.bpel.obj.serde;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import javax.wsdl.OperationType;
import javax.wsdl.Part;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.bpel.obj.OProcess;
import org.apache.ode.bpel.obj.serde.jacksonhack.TypeBeanSerializerFactory;
import org.apache.ode.utils.NSContext;
import org.w3c.dom.Element;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
import com.fasterxml.jackson.module.jaxb.ser.DomElementJsonSerializer;
import com.ibm.wsdl.MessageImpl;

/**
 * OModel Serializer that serialize process to json using jackson.
 * Corresponding to format {@link OmSerdeFactory.SerializeFormat#FORMAT_SERIALIZED_JSON}
 * @see JsonOmDeserializer
 */
public class JsonOmSerializer implements OmSerializer {
	protected static final Log __log = LogFactory
			.getLog(JsonOmSerializer.class);

	private OutputStream os;
	private OProcess process;

	private ObjectMapper mapper;
	protected JsonFactory factory;
	private Map<Class<?>, JsonSerializer<?>> serializers;

	public JsonOmSerializer() {
		serializers = new HashMap<Class<?>, JsonSerializer<?>>();
		addCustomSerializer(OperationType.class, new OperationTypeSerializer());
		addCustomSerializer(Element.class, new DomElementSerializerHack());
		addCustomSerializer(NSContext.class, new NSContextSerializer(NSContext.class));
		addCustomSerializer(MessageImpl.class, new MessageSerializer(MessageImpl.class));
	}

	public JsonOmSerializer(OutputStream os, OProcess process){
		this(os, process, new JsonFactory());
	}

	protected JsonOmSerializer(OutputStream os, OProcess process,
			JsonFactory factory) {
		this();
		this.os = os;
		this.process = process;
		this.factory = factory;
	}

	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void serialize(){
		mapper = new ObjectMapper(factory);
		mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		mapper.setSerializerFactory(TypeBeanSerializerFactory.instance);
		SimpleModule simpleModule = new SimpleModule("SimpleModule");
		for (Class<?> ss : serializers.keySet()) {
			simpleModule.addSerializer((Class) ss,
					(JsonSerializer) serializers.get(ss));
		}

		simpleModule.addKeySerializer(Object.class, new KeyAsJsonSerializer());
		mapper.registerModule(simpleModule);
		
		mapper.enable(SerializationFeature.INDENT_OUTPUT);
		try {
			mapper.writeValue(os, process);
			os.flush();
		} catch (Exception e) {
			SerializaionRtException se = new SerializaionRtException("error when serialize process");
			se.initCause(e);
			throw se;
		}
	}

	public void addCustomSerializer(Class<?> c, JsonSerializer<?> ss) {
		if (serializers.containsKey(c)) {
			__log.warn("Serializer for type " + c
					+ " has been added. Removed previous one");
		}
		serializers.put(c, ss);
	}

	public JsonSerializer<?> removeCustomSerializer(Class<?> c) {
		return serializers.remove(c);
	}

	public OutputStream getOs() {
		return os;
	}

	public void setOs(OutputStream os) {
		this.os = os;
	}

	/**
	 * Custom jackson serializer for {@link OperationType}
	 * @see JsonOmDeserializer.OperationTypeDeserializer
	 */
	public static class OperationTypeSerializer extends
			StdScalarSerializer<OperationType> {

		protected OperationTypeSerializer() {
			super(OperationType.class, false);
		}

		@Override
		public void serialize(OperationType value, JsonGenerator jgen,
				SerializerProvider provider) throws IOException,
				JsonGenerationException {
			if (OperationType.ONE_WAY.equals(value)) {
				jgen.writeString("ONE_WAY");
			} else if (OperationType.REQUEST_RESPONSE.equals(value)) {
				jgen.writeString("REQUEST_RESPONSE");
			} else if (OperationType.SOLICIT_RESPONSE.equals(value)) {
				jgen.writeString("SOLICIT_RESPONSE");
			} else if (OperationType.NOTIFICATION.equals(value)) {
				jgen.writeString("NOTIFICATION");
			} else {
				// unknown type
				jgen.writeString(value.toString());
			}
		}

		@Override
		public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
			return createSchemaNode("string", true);
		}

	}
	
	public static class DomElementSerializerHack extends DomElementJsonSerializer{
	    @Override
	    public void serializeWithType(Element value, JsonGenerator jgen, SerializerProvider provider,
	            TypeSerializer typeSer)
				throws IOException, JsonGenerationException {
			String typeId = "org.w3c.dom.Element";
			jgen.writeStartArray();
			jgen.writeString(typeId);
			serialize(value, jgen, provider);
			jgen.writeEndArray();
		}
	}
	/**
	 * Custom {@link NSContext} serializer. Serialize it's map representation.
	 * @see NSContext JsonOmDeserializer.NSContextDeserializer
	 */
	public static class NSContextSerializer extends StdScalarSerializer<NSContext>{

	
		protected NSContextSerializer(Class<NSContext> t) {
			super(t);
		}

		@SuppressWarnings({ "unchecked", "rawtypes" })
		@Override
		public void serialize(NSContext value, JsonGenerator jgen,
				SerializerProvider provider) throws IOException,
				JsonGenerationException {
			jgen.writeObject(new HashMap(value.toMap()));
		}
		
	}
	
	/**
	 * custom serializer for {@link MessageImpl}. Additional private field 
	 * (@link MessageImpl#additionOrderOfParts} are serialized.
	 * 
	 * @see JsonOmDeserializer.MessageDeserializer
	 */
	public static class MessageSerializer extends StdScalarSerializer<MessageImpl>{

		protected MessageSerializer(Class<MessageImpl> class1) {
			super(class1);
		}

		@Override
		public void serialize(MessageImpl value, JsonGenerator jgen,
				SerializerProvider provider) throws IOException,
				JsonGenerationException {
			jgen.writeObject(value.getDocumentationElement());
			jgen.writeObject(value.getExtensibilityElements());
			jgen.writeObject(value.getExtensionAttributes());

			jgen.writeObject(value.getParts());
			jgen.writeObject(value.getNativeAttributeNames());
			jgen.writeObject(value.isUndefined());
			jgen.writeObject(value.getQName());
			try {
				Field f = value.getClass().getDeclaredField("additionOrderOfParts");
				f.setAccessible(true);
				Vector<Part> parts = (Vector)f.get(value);
				jgen.writeObject(parts);
			} catch (Exception e) {
				//nothing to do.
				__log.debug("Exception when serialize MessageImpl:" + e);
			}
		}
		
	}

}
