package com.ym.im.handler;

import com.ym.im.entity.base.BaseSocketInfo;
import com.ym.im.entity.MsgBody;
import com.ym.im.entity.base.NettyConstant;
import com.ym.im.entity.enums.PlatformEnum;
import com.ym.im.exception.HttpException;
import com.ym.im.factory.SingleChatFactory;
import com.ym.im.service.ChannelGroupService;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Optional;

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


/**
 * @author: JJww
 * @Date:2020/10/10
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class WebSocketHandshakerHandler extends BaseHandler<FullHttpRequest> {

    @Autowired
    private SingleChatFactory singleChatFactory;

    public static final String AUTHORIZATION = "Authorization";

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

        final String token = fullHttpRequest.headers().get(AUTHORIZATION);
        Optional.ofNullable(token).orElseThrow(() -> new HttpException(ctx, fullHttpRequest, new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED)));
        Long userId = 0L;//待完善鉴权逻辑
        Integer type = 1;
        ctx.channel().attr(NettyConstant.ID).set(userId);
        ctx.channel().attr(NettyConstant.TOKEN_INFO).set(token);
        this.sso(token, userId, "tokenInfo[0]");
        singleChatFactory.getService(type).init(ctx);
        fullHttpRequest.setUri(NettyConstant.CS);
        ctx.fireChannelRead(fullHttpRequest.retain());
        log.info(userId + " 上线");
    }


    private void sso(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.writeAndFlush(new MsgBody<>().setStatus(MsgBody.FORCEDOFFLINE));
            baseSocketInfo.getChannel().close();
            ChannelGroupService.USER_GROUP.remove(userId);
            log.info("用户: " + userId + " 被迫下线");
        }
    }
}
