package com.cm.socket.decoder;

import com.cm.socket.enums.SocketMessageEnum;
import com.cm.socket.enums.SocketTypeMessageEnum;
import com.cm.socket.pojo.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: MessageDecoder
 * @Description: 消息解码器
 * @Author: WangGeng
 * @Date: 2020/7/4 16:11
 * @Version: 1.0
 **/
public class MessageDecoder extends ByteToMessageDecoder {
    /**
     * 头部长度 1byte + 1byte + 4byte + 4byte
     */
    private static final int HEADER_LENGTH = 10;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in == null) {
            return;
        }
        if (in.readableBytes() < HEADER_LENGTH) {
            return;
        }
        in.markReaderIndex();
        byte start = in.readByte();
        byte type = in.readByte();
        int tokenBytesLength = in.readInt();
        int contentBytesLength = in.readInt();
        if (in.readableBytes() < contentBytesLength) {
            in.resetReaderIndex();
            return;
        }
        String token = getToken(in, tokenBytesLength);
        String content = getContent(in, contentBytesLength);
        Message tempMessage = new Message();
        tempMessage.setStart(start);
        tempMessage.setType(type);
        tempMessage.setToken(token);
        tempMessage.setContent(content);
        out.add(tempMessage);
    }

    /**
     * 获取ID
     *
     * @param in
     * @return
     */
    private String getToken(ByteBuf in, int tokenBytesLength) {
        if (tokenBytesLength <= 0) {
            return null;
        }
        if (in.readableBytes() < tokenBytesLength) {
            return null;
        }
        byte[] tokenBytes = new byte[tokenBytesLength];
        in.readBytes(tokenBytes);
        return new String(tokenBytes, CharsetUtil.UTF_8);
    }

    /**
     * 获取内容
     *
     * @param in
     * @return
     */
    private String getContent(ByteBuf in, int contentBytesLength) {
        if (contentBytesLength <= 0) {
            return null;
        }
        if (in.readableBytes() < contentBytesLength) {
            return null;
        }
        byte[] contentBytes = new byte[contentBytesLength];
        in.readBytes(contentBytes);
        return new String(contentBytes, CharsetUtil.UTF_8);
    }
}
