/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.ui.impl;

import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Web socket servlet capable of creating web sockets for the user interface.
 */
public class UiWebSocketServlet extends WebSocketServlet {

    private static final long PING_DELAY_MS = 5000;

    private static UiWebSocketServlet instance;

    private ServiceDirectory directory = new DefaultServiceDirectory();

    private final Set<UiWebSocket> sockets = new HashSet<>();
    private final Timer timer = new Timer();
    private final TimerTask pruner = new Pruner();
    private boolean isStopped = false;

    /**
     * Closes all currently open UI web-sockets.
     */
    public static void closeAll() {
        if (instance != null) {
            instance.isStopped = true;
            instance.sockets.forEach(UiWebSocket::close);
            instance.sockets.clear();
            instance.pruner.cancel();
            instance.timer.cancel();
        }
    }

    @Override
    public void init() throws ServletException {
        super.init();
        instance = this;
        timer.schedule(pruner, PING_DELAY_MS, PING_DELAY_MS);
    }

    @Override
    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
        if (isStopped) {
            return null;
        }

        // FIXME: Replace this with globally shared opaque token to allow secure failover
        Principal p = request.getUserPrincipal();
        String userName = p != null ? p.getName() : FAKE_USERNAME;

        UiWebSocket socket = new UiWebSocket(directory, userName);
        synchronized (sockets) {
            sockets.add(socket);
        }
        return socket;
    }

    // FIXME: This should not be necessary
    private static final String FAKE_USERNAME = "UI-user";

    /**
     * Sends the specified message to all the GUI clients.
     *
     * @param type    message type
     * @param payload message payload
     */
    static void sendToAll(String type, ObjectNode payload) {
        if (instance != null) {
            instance.sockets.forEach(ws -> ws.sendMessage(type, 0, payload));
        }
    }

    /**
     * Sends the specified message to all the GUI clients of the specified user.
     *
     * @param userName user name
     * @param type     message type
     * @param payload  message payload
     */
    static void sendToUser(String userName, String type, ObjectNode payload) {
        if (instance != null) {
            instance.sockets.stream().filter(ws -> userName.equals(ws.userName()))
                    .forEach(ws -> ws.sendMessage(type, 0, payload));
        }
    }

    // Task for pruning web-sockets that are idle.
    private class Pruner extends TimerTask {
        @Override
        public void run() {
            synchronized (sockets) {
                Iterator<UiWebSocket> it = sockets.iterator();
                while (it.hasNext()) {
                    UiWebSocket socket = it.next();
                    if (socket.isIdle()) {
                        it.remove();
                        socket.close();
                    }
                }
            }
        }
    }
}
