package Webpage;

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIONamespace;
import com.corundumstudio.socketio.SocketIOServer;
import lombok.NonNull;
import lombok.Setter;
import org.pmw.tinylog.Logger;

import java.util.function.Function;

public class SocketioServer {
    private final SocketIOServer server;
    private @Setter Function<@NonNull SocketioRequest, @NonNull SocketioResponse> onRequest;

    /**
     * Create Socket.io Server
     * @param localip Local Ip address to bind.<br/>if null or empty will default to 0.0.0.0
     * @param listenport Local Port to bind.<br/>if invalid, will default to 9092
     */
    public SocketioServer(String localip,int listenport){
        if (localip==null || localip.isEmpty()) localip="0.0.0.0";
        if (listenport<=0 || listenport>65535) listenport=9092;
        Configuration config = new Configuration();
        config.setHostname(localip);
        config.setPort(listenport);

        server = new SocketIOServer(config);
        SocketIONamespace socketio = server.addNamespace("/socketio");
        socketio.addConnectListener(client -> Logger.info("Client id={} remoteaddress={} Connected to /socketio: " , client.getSessionId(), client.getRemoteAddress()));
        socketio.addDisconnectListener(client -> Logger.info("Client id={} remoteaddress={} Disconnected from /socketio: ", client.getSessionId(), client.getRemoteAddress()));
        socketio.addEventListener("command", SocketioRequest.class, (client, data, ackRequest) -> {
            Logger.info("Client id={} remoteaddress={} request: {}", client.getSessionId(), client.getRemoteAddress(), data);
            if (onRequest!=null){
                SocketioResponse response = onRequest.apply(data);
                Logger.info("Client id={} remoteaddress={} response: {}", client.getSessionId(), client.getRemoteAddress(), response);
                ackRequest.sendAckData(response);
            }
        });

    }

    /**
     * Start the server
     */
    public void Start(){
        if (server!=null) server.start();
    }

    /**
     * Stop the server
     */
    public void Stop(){
        if (server!=null) server.stop();
    }
}
