/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 static final Object INSTANCE_LOCK = new Object();

    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() {
        synchronized (INSTANCE_LOCK) {
            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();
        synchronized (INSTANCE_LOCK) {
            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) {
        synchronized (INSTANCE_LOCK) {
            if (instance != null) {
                instance.sockets.forEach(ws -> ws.sendMessage(type, 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) {
        synchronized (INSTANCE_LOCK) {
            if (instance != null) {
                instance.sockets.stream().filter(ws -> userName.equals(ws.userName()))
                        .forEach(ws -> ws.sendMessage(type, 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();
                    }
                }
            }
        }
    }
}
