package com.yida.data.websocket.config;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yida.data.common.core.entity.CurrentUser;
import java.util.LinkedHashMap;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.stereotype.Component;

/**
 * 连接鉴权
 */
@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
@RequiredArgsConstructor
public class AuthIntercentor implements ChannelInterceptor {

    private final ResourceServerTokenServices resourceServerTokenServices;

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        //判断是否首次连接
        if (accessor != null && StompCommand.CONNECT.equals(accessor.getCommand())) {
            List<String> authorization = accessor.getNativeHeader("Authorization");
            log.info("websocket认证:[{}]", authorization);
            boolean isLogin = false;
            if (CollUtil.isNotEmpty(authorization)) {
                try {
                    OAuth2Authentication oAuth2Authentication = resourceServerTokenServices
                        .loadAuthentication(authorization.get(0));
                    LinkedHashMap<String, Object> authenticationDetails = (LinkedHashMap<String, Object>) oAuth2Authentication
                        .getUserAuthentication().getDetails();
                    Object principal = authenticationDetails.get("principal");
                    ObjectMapper mapper = new ObjectMapper();
                    CurrentUser currentUser = mapper.readValue(mapper.writeValueAsString(principal), CurrentUser.class);
                    log.info("获取到用户:[{}]", currentUser);
                    isLogin = true;
                } catch (Exception e) {
                    log.error("错误:", e);
                }
            }
            return isLogin ? message : null;
        }
        return message;
    }

}
