package omq.common.util.Serializers;

import java.io.ByteArrayOutputStream;

import omq.exception.SerializerException;


import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/**
 * 
 * @author Sergi Toda <sergi.toda@estudiants.urv.cat>
 * @author Guillermo Guerrero <guillermo.guerrero@estudiants.urv.cat>
 * 
 */
public class KryoImp implements ISerializer {
	private final Kryo kryo = new Kryo();

	@Override
	public byte[] serialize(Object obj) throws SerializerException {
		try {
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			Output output = new Output(stream);
			kryo.writeClassAndObject(output, obj);
			
			output.flush();
			output.close();

			byte[] bArray = stream.toByteArray();

			stream.flush();
			stream.close();

			return bArray;
		} catch (Exception e) {
			throw new SerializerException("Serialize -> " + e.getMessage(), e);
		}
	}
	
	@Override
	public byte[] serialize(Object obj, Class<?> clazz) throws SerializerException {
		try {
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			Output output = new Output(stream);
			kryo.writeObject(output, obj);
			
			output.flush();
			output.close();

			byte[] bArray = stream.toByteArray();

			stream.flush();
			stream.close();

			return bArray;
		} catch (Exception e) {
			throw new SerializerException("Serialize -> " + e.getMessage(), e);
		}
	}
	

	@Override
	public Object deserialize(byte[] bytes) throws SerializerException {
		try {
			Input input = new Input(bytes);
			Object obj = kryo.readClassAndObject(input);

			input.close();
			return obj;
		} catch (Exception e) {
			throw new SerializerException("Deserialize -> " + e.getMessage(), e);
		}
	}

	@Override
	public Object deserialize(byte[] bytes, Class<?> clazz) throws SerializerException {
		try {
			Input input = new Input(bytes);
			Object obj = kryo.readObject(input, clazz);

			input.close();
			return obj;
		} catch (Exception e) {
			throw new SerializerException("Deserialize -> " + e.getMessage(), e);
		}		
	}
}
