package com.ym.im.handler;


import com.ym.im.entity.BaseSocketInfo;
import com.ym.im.entity.LanguageEnum;
import com.ym.im.entity.MsgBody;
import com.ym.im.entity.NettyConstant;
import com.ym.im.entity.enums.PlatformEnum;
import com.ym.im.factory.SingleChatFactory;
import com.ym.im.service.ChannelGroupService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

import static io.netty.handler.codec.http.HttpResponseStatus.UNAUTHORIZED;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * @author: JJww
 * ws 校验/初始化相关处理
 * @Date:2019-05-17
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class IndexHandler extends BaseHandler<FullHttpRequest> {

    @Resource(name = "myRedisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private SingleChatFactory singleChatFactory;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {

        // 获取uri参数信息
        final Map<String, List<String>> parameters = new QueryStringDecoder(request.uri()).parameters();
        // 获取token信息
        final List<String> tokenStr = parameters.get(NettyConstant.TOKEN);
        if (tokenStr == null) {
            log.error("token值为空！");
            sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED));
            return;
        }
        // 解析token
//        final String[] tokenInfo = String.valueOf(JwtUtil.checkToken(tokenStr.get(0)).get("user_id")).split("_");
        final String[] tokenInfo = null;
        if (tokenInfo.length < 2) {
            log.error("userId格式不正确：" + tokenInfo[1]);
            sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED));
            return;
        }
        final Integer type = NettyConstant.CONNECT_TYPE.get(tokenInfo[0]);
        final Long userId = Long.valueOf(tokenInfo[1]);
        if (type == null) {
            log.error("用户类型值不正确：" + tokenInfo[0]);
            sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED));
            return;
        }
//        if (NettyConstant.CONNECT_TYPE_USER == type.intValue() && Constants.FORBIDDEN.equals(redisTemplate.opsForHash().get(Constants.USER, userId))) {
//            log.info("用户被禁用：" + userId);
//            sendHttpResponse(ctx, request, new DefaultFullHttpResponse(HTTP_1_1, PROXY_AUTHENTICATION_REQUIRED));
//            return;
//        }
        //保存当前token
        String token = "Bearer " + tokenStr.get(0);
        ctx.channel().attr(NettyConstant.TOKEN_INFO).set(token);
        ctx.channel().attr(NettyConstant.ID).set(userId);
        ctx.channel().attr(NettyConstant.COL_INFO).set(parameters.get(NettyConstant.COL) == null ? LanguageEnum.zh.getKey() : parameters.get(NettyConstant.COL).get(0));
        this.close(token, userId, tokenInfo[0]);
        singleChatFactory.getService(type).init(ctx);
        request.setUri(NettyConstant.WS);
        ctx.fireChannelRead(request.retain());
    }


    private void close(String token, Long userId, String type) {
        final BaseSocketInfo baseSocketInfo = PlatformEnum.app.getKey().equals(type) ? ChannelGroupService.USER_GROUP.get(userId) : ChannelGroupService.STAFF_GROUP.get(userId);
        if (baseSocketInfo != null && !token.equals(baseSocketInfo.getToken())) {
            baseSocketInfo.getChannel().write(new MsgBody(MsgBody.FORCEDOFFLINE));
            baseSocketInfo.getChannel().close();
            ChannelGroupService.USER_GROUP.remove(userId);
            log.info("用户: " + userId + " 被迫下线");
        }
    }


    private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) {

        if (response.status().code() != HttpResponseStatus.OK.code()) {
            ByteBuf buf = Unpooled.copiedBuffer(response.status().toString(), CharsetUtil.UTF_8);
            response.content().writeBytes(buf);
            buf.release();
            response.headers();
            HttpUtil.setContentLength(response, response.content().readableBytes());
        }

        ChannelFuture f = ctx.channel().writeAndFlush(response);
        if (!HttpUtil.isKeepAlive(request) || response.status().code() != HttpResponseStatus.OK.code()) {
            f.addListener(ChannelFutureListener.CLOSE);
        }
    }


}