package projet;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;


@ServerEndpoint("/ws/bloc")
public class BlocCollaborative {

	private static final Map<String, Set<Session>> sessionsParPage = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session) {
    	String query = session.getQueryString();
    	String pageId = extractPageId(query);
    	session.getUserProperties().put("pageId", pageId);
    	
    	sessionsParPage.computeIfAbsent(pageId, k -> ConcurrentHashMap.newKeySet()).add(session);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
    	String pageId = (String) session.getUserProperties().get("pageId");
    	Set<Session> sessions = sessionsParPage.get(pageId);
    	
    	Lock sessionLock = new ReentrantLock();
    	
    	synchronized (sessions) {
            for (Session s : sessions) {
                if (s.isOpen() && !s.equals(session)) {
                    sessionLock.lock();
                    try {
                        s.getAsyncRemote().sendText(message);
                    } finally {
                        sessionLock.unlock();
                    }
                }
            }
        }
    }

    @OnClose
    public void onClose(Session session) {
        String pageId = (String) session.getUserProperties().get("pageId");
        if (pageId != null) {
            Set<Session> sessions = sessionsParPage.get(pageId);
            if (sessions != null) {
                sessions.remove(session);
                if (sessions.isEmpty()) {
                    sessionsParPage.remove(pageId);
                }
            }
        }
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }
    
    private String extractPageId(String query) {
        for (String param : query.split("&")) {
            String[] kv = param.split("=");
            if (kv.length == 2 && kv[0].equals("pageId")) {
                return kv[1];
            }
        }
        return "default";
    }
}
