package com.shanghaichengdi.ghjgitem.cache;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.lang.Nullable;

/**
 * @author gengaoliu
 */
public class ProtostuffSerializer implements RedisSerializer<Object> {

  private final Schema<ProtoWrapper> schema;
  private final ProtoWrapper wrapper;
  private final LinkedBuffer buffer;

  public ProtostuffSerializer() {
    this.wrapper = new ProtoWrapper();
    this.schema = RuntimeSchema.getSchema(ProtoWrapper.class);
    this.buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
  }

  private boolean isEmpty(byte[] data) {
    return data == null || data.length == 0;
  }

  @Nullable
  @Override
  public byte[] serialize(Object t) throws SerializationException {
    if (t == null) {
      return new byte[0];
    }
    wrapper.data = t;
    try {
      return ProtostuffIOUtil.toByteArray(wrapper, schema, buffer);
    } finally {
      buffer.clear();
    }
  }

  @Nullable
  @Override
  public Object deserialize(byte[] bytes) throws SerializationException {
    if (isEmpty(bytes)) {
      return null;
    }
    ProtoWrapper newMessage = schema.newMessage();
    ProtostuffIOUtil.mergeFrom(bytes, newMessage, schema);
    return newMessage.data;
  }

  private static class ProtoWrapper {

    public Object data;
  }
}
