package omq.common.util.Serializers;

import omq.common.message.request.AsyncRequest;
import omq.common.message.request.SyncRequest;
import omq.common.message.response.CollectionResponse;
import omq.common.message.response.DefaultResponse;
import omq.common.message.response.ExceptionResponse;
import omq.common.message.response.ProxyResponse;
import omq.common.message.response.Response;
import omq.exception.SerializerException;

import com.google.gson.Gson;


public class GsonImp implements ISerializer {
	private final Gson gson = new Gson();
	
	@Override
	public byte[] serialize(Object obj) throws SerializerException {
		String output = gson.toJson(obj);
		return output.getBytes();
	}
	
	@Override
	public byte[] serialize(Object obj, Class<?> clazz) throws SerializerException {
		return serialize(obj);
	}	

	private Object tryDeserialize(byte[] bytes, Class<?> clazz) throws Exception{
		String input = new String(bytes);
		Object object = gson.fromJson(input, clazz);
		return object;
	}
	
	@Override
	public Object deserialize(byte[] bytes) throws SerializerException {
		try {
			return tryDeserialize(bytes, SyncRequest.class);
		} catch (Exception e) {
			try {
				return tryDeserialize(bytes, AsyncRequest.class);
			} catch (Exception e1) {				
				try {
					return tryDeserialize(bytes, CollectionResponse.class);					
				} catch (Exception e2) {
					try {
						return tryDeserialize(bytes, DefaultResponse.class);					
					} catch (Exception e3) {						
						try {
							return tryDeserialize(bytes, ExceptionResponse.class);					
						} catch (Exception e4) {							
							try {
								return tryDeserialize(bytes, ProxyResponse.class);					
							} catch (Exception e5) {								
								try {
									return tryDeserialize(bytes, Response.class);					
								} catch (Exception e6) {
									throw new SerializerException("Deserialize -> " + e6.getMessage(), e6);
								}								
							}							
						}						
					}
				}				
			} 
		}		
	}

	@Override
	public Object deserialize(byte[] bytes, Class<?> clazz) throws SerializerException {
		try {
			return tryDeserialize(bytes, clazz);
		} catch (Exception e) {
			throw new SerializerException("Deserialize -> " + e.getMessage(), e);
		}
	}

}
