package com.nokia.hb.config.web;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 网络套接字握手拦截器
 *
 * @author x
 * @date 2023/03/07
 */
@Slf4j
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
    /**
     * Invoked before the handshake is processed.
     *
     * @param request    the current request
     * @param response   the current response
     * @param wsHandler  the target WebSocket handler
     * @param attributes the attributes from the HTTP handshake to associate with the WebSocket
     *                   session; the provided attributes are copied, the original map is not used.
     * @return whether to proceed with the handshake ({@code true}) or abort ({@code false})
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request;
        HttpServletRequest httpServletRequest = servletServerHttpRequest.getServletRequest();
        String username = httpServletRequest.getParameter("username");
        Cookie[] cookies = httpServletRequest.getCookies();
        log.debug("username: {}", username);
        log.debug("cookies: {}", JSON.toJSONString(cookies));
        if (cookies == null) {
            log.warn("cookies is null");
            return false;
        }
        String sessionId = null;
        for (Cookie cookie : cookies) {
            if ("JSESSIONID".equals(cookie.getName())) {
                sessionId = cookie.getValue();
                log.debug("JSESSIONID: {}", sessionId);
                attributes.put("JSESSIONID", sessionId);
            }
        }
        if (!StringUtils.hasText(sessionId)) {
            log.warn("JSESSIONID is null");
            return false;
        }
        attributes.put("username", username);
        return true;
    }

    /**
     * Invoked after the handshake is done. The response status and headers indicate
     * the results of the handshake, i.e. whether it was successful or not.
     *
     * @param request   the current request
     * @param response  the current response
     * @param wsHandler the target WebSocket handler
     * @param exception an exception raised during the handshake, or {@code null} if none
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception exception) {
        if (exception != null) {
            log.error(exception.getMessage(), exception);
        }
    }
}
