package com.ikasoa.rpc.handler.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Optional;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.ikasoa.rpc.handler.ProtocolHandler;
import com.ikasoa.rpc.handler.ReturnData;
import com.ikasoa.rpc.utils.Base64Util;

import lombok.NoArgsConstructor;

/**
 * 转换协议处理器Kryo实现
 * 
 * @author <a href="mailto:larry7696@gmail.com">Larry</a>
 * @version 0.1
 */
@NoArgsConstructor
public class KryoProtocolHandlerImpl<T, R> implements ProtocolHandler<T, R> {

	private ReturnData resultData;

	private Kryo kryo;

	public KryoProtocolHandlerImpl(ReturnData resultData) {
		this.resultData = resultData;
		this.kryo = new Kryo();
	}

	@Override
	@SuppressWarnings("unchecked")
	public T strToArg(String str) {
		return (T) kryo.readObject(new Input(Base64Util.decode(str)), kryo.register(Object[].class).getType());
	}

	@Override
	@SuppressWarnings("unchecked")
	public String argToStr(T arg) {
		arg = Optional.ofNullable(arg).orElse((T) new Object[0]);
		Output output = new Output(1, 4096);
		kryo.writeObject(output, arg);
		byte[] bb = output.toBytes();
		output.flush();
		return Base64Util.encode(bb);
	}

	@Override
	public String resultToStr(R result) {
		if (result == null)
			return String.valueOf(V);
		Output output = new Output(1, 4096);
		kryo.writeObject(output, result);
		byte[] bb = output.toBytes();
		output.flush();
		return Base64Util.encode(bb);
	}

	@Override
	@SuppressWarnings("unchecked")
	public R strToResult(String str) {
		if (String.valueOf(V).equals(str))
			return null;
		return resultData.isArray()
				? (R) kryo.readObject(new Input(Base64Util.decode(str)),
						kryo.register((new ArrayList<>()).getClass()).getType())
				: resultData.isMap()
						? (R) kryo.readObject(new Input(Base64Util.decode(str)),
								kryo.register((new HashMap<>()).getClass()).getType())
						: (R) kryo.readObject(new Input(Base64Util.decode(str)),
								kryo.register(resultData.getClassType()).getType());
	}

	@Override
	public Throwable strToThrowable(String str) {
		// TODO: 该实现暂不对异常返回做处理
		return null;
	}

	@Override
	public ReturnData getReturnData() {
		return resultData;
	}

}

@@ -1140,24 +1140,29 @@
 ect%5B0%5D);%0D%0A%09%09
+try (
 Output outpu
@@ -1176,35 +1176,38 @@
  Output(1, 4096)
-;
+) %7B
 %0D%0A
+%09
 %09%09kryo.writeObje
@@ -1222,24 +1222,25 @@
 t, arg);%0D%0A%09%09
+%09
 byte%5B%5D bb = 
@@ -1250,32 +1250,33 @@
 put.toBytes();%0D%0A
+%09
 %09%09output.flush()
@@ -1272,32 +1272,33 @@
 put.flush();%0D%0A%09%09
+%09
 return Base64Uti
@@ -1304,32 +1304,37 @@
 il.encode(bb);%0D%0A
+%09%09%7D%0D%0A
 %09%7D%0D%0A%0D%0A%09@Override
@@ -1327,32 +1327,65 @@
 %0D%0A%0D%0A%09@Override%0D%0A
+%09@SuppressWarnings(%22unchecked%22)%0D%0A
 %09public String r
@@ -1414,20 +1414,16 @@
 %0D%0A%09%09
-if (
 result =
 = nu
@@ -1422,26 +1422,47 @@
 lt =
-= null)%0D%0A%09%09%09return
+ Optional.ofNullable(result).orElse((R)
  Str
@@ -1475,21 +1475,27 @@
 lueOf(V)
+)
 ;%0D%0A%09%09
+try (
 Output o
@@ -1521,19 +1521,22 @@
 1, 4096)
-;
+) %7B
 %0D%0A
+%09
 %09%09kryo.w
@@ -1564,16 +1564,17 @@
 sult);%0D%0A
+%09
 %09%09byte%5B%5D
@@ -1600,16 +1600,17 @@
 s();%0D%0A%09%09
+%09
 output.f
@@ -1618,16 +1618,17 @@
 ush();%0D%0A
+%09
 %09%09return
@@ -1648,24 +1648,29 @@
 ncode(bb);%0D%0A
+%09%09%7D%0D%0A
 %09%7D%0D%0A%0D%0A%09@Over
@@ -1909,25 +1909,24 @@
 yo.register(
-(
 new ArrayLis
@@ -1929,17 +1929,17 @@
 yList%3C%3E(
-)
+0
 ).getCla
@@ -2068,17 +2068,16 @@
 egister(
-(
 new Hash
@@ -2082,17 +2082,17 @@
 shMap%3C%3E(
-)
+0
 ).getCla

optimize codes & bugfix