/*
 * 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 com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
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.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 = Sets.newConcurrentHashSet();
    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);
        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() {
            ImmutableSet<UiWebSocket> set = ImmutableSet.copyOf(sockets);
            set.stream().filter(UiWebSocket::isIdle).forEach(s -> {
                sockets.remove(s);
                s.close();
            });
        }
    }
}
