package common.network;

import java.util.List;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;

import common.net.buffer.ByteBuf;
import common.net.buffer.Unpooled;
import common.net.channel.ChannelHandlerContext;
import common.net.handler.codec.ByteToMessageDecoder;
import common.net.handler.codec.DecoderException;

public class CompressionDecoder extends ByteToMessageDecoder {
	private final Inflater inflater;
	private int treshold;

	public CompressionDecoder(int treshold) {
		this.treshold = treshold;
		this.inflater = new Inflater();
	}

	protected void decode(ChannelHandlerContext context, ByteBuf buffer, List<Object> output) throws DataFormatException, Exception {
		if(buffer.readableBytes() == 0)
			return;
		PacketBuffer pbuf = new PacketBuffer(buffer);
		int len = pbuf.readVarInt();
		if(len == 0) {
			output.add(pbuf.readBytes(pbuf.readableBytes()));
			return;
		}
		if(len < this.treshold)
			throw new DecoderException("Badly compressed packet - size of " + len + " is below server threshold of " + this.treshold);
		if(len > 20971520)
			throw new DecoderException("Badly compressed packet - size of " + len + " is larger than protocol maximum of " + 20971520);
		byte[] comp = new byte[pbuf.readableBytes()];
		pbuf.readBytes(comp);
		this.inflater.setInput(comp);
		byte[] data = new byte[len];
		this.inflater.inflate(data);
		output.add(Unpooled.wrappedBuffer(data));
		this.inflater.reset();
	}

	public void setTreshold(int treshold) {
		this.treshold = treshold;
	}
}
