package com.ttstd.signaling.security;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

import java.util.List;
import java.util.Map;

/**
 * 子协议协商处理器。
 *
 * <p>客户端以 {@code Sec-WebSocket-Protocol: signal.v1, auth.<token>} 传递令牌时，
 * 服务端必须在响应中回显一个已选择的子协议，否则浏览器会判定协商失败并断开连接。
 * 此处固定回显 {@code signal.v1}，绝不回显携带令牌的那一项。
 */
@Component
public class SubProtocolHandshakeHandler extends DefaultHandshakeHandler {

    @Override
    protected String selectProtocol(List<String> requestedProtocols, WebSocketHandler webSocketHandler) {
        if (requestedProtocols == null) {
            return null;
        }
        for (String protocol : requestedProtocols) {
            if ("signal.v1".equals(protocol.trim())) {
                return "signal.v1";
            }
        }
        return null;
    }

    @Override
    protected java.security.Principal determineUser(ServerHttpRequest request,
                                                    WebSocketHandler wsHandler,
                                                    Map<String, Object> attributes) {
        Object principal = attributes.get(AuthHandshakeInterceptor.ATTR_PRINCIPAL);
        if (principal instanceof com.ttstd.signaling.model.AuthPrincipal auth) {
            return auth::deviceId;
        }
        return null;
    }
}
