/*
 * Copyright 2015 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;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.osgi.ServiceDirectory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Abstraction of an entity capable of processing JSON messages from the user
 * interface client.
 * <p>
 * The message structure is:
 * </p>
 * <pre>
 * {
 *     "type": "<em>event-type</em>",
 *     "payload": {
 *         <em>arbitrary JSON object structure</em>
 *     }
 * }
 * </pre>
 * On {@link #init initialization} the handler will create and cache
 * {@link RequestHandler} instances, each of which are bound to a particular
 * <em>event-type</em>. On {@link #process arrival} of a new message,
 * the <em>event-type</em> is determined, and the message dispatched to the
 * corresponding <em>RequestHandler</em>'s
 * {@link RequestHandler#process process} method.
 */
public abstract class UiMessageHandler {

    private final Logger log = LoggerFactory.getLogger(getClass());
    private final Map<String, RequestHandler> handlerMap = new HashMap<>();

    private final ObjectMapper mapper = new ObjectMapper();

    private UiConnection connection;
    private ServiceDirectory directory;


    /**
     * Subclasses must create and return the collection of request handlers
     * for the message types they handle.
     * <p>
     * Note that request handlers should be stateless. When we are
     * {@link #destroy destroyed}, we will simply drop our references to them
     * and allow them to be garbage collected.
     *
     * @return the message handler instances
     */
    protected abstract Collection<RequestHandler> createRequestHandlers();

    /**
     * Returns the set of message types which this handler is capable of
     * processing.
     *
     * @return set of message types
     */
    public Set<String> messageTypes() {
        return Collections.unmodifiableSet(handlerMap.keySet());
    }

    /**
     * Processes a JSON message from the user interface client.
     *
     * @param message JSON message
     */
    public void process(ObjectNode message) {
        String type = JsonUtils.eventType(message);
        ObjectNode payload = JsonUtils.payload(message);
        // TODO: remove sid
        exec(type, 0, payload);
    }

    /**
     * Finds the appropriate handler and executes the process method.
     *
     * @param eventType event type
     * @param sid       sequence identifier
     * @param payload   message payload
     */
    // TODO: remove sid from signature
    void exec(String eventType, long sid, ObjectNode payload) {
        RequestHandler requestHandler = handlerMap.get(eventType);
        if (requestHandler != null) {
            requestHandler.process(sid, payload);
        } else {
            log.warn("no request handler for event type {}", eventType);
        }
    }

    /**
     * Initializes the handler with the user interface connection and
     * service directory context.
     *
     * @param connection user interface connection
     * @param directory  service directory
     */
    public void init(UiConnection connection, ServiceDirectory directory) {
        this.connection = connection;
        this.directory = directory;

        Collection<RequestHandler> handlers = createRequestHandlers();
        checkNotNull(handlers, "Handlers cannot be null");
        checkArgument(!handlers.isEmpty(), "Handlers cannot be empty");

        for (RequestHandler h : handlers) {
            h.setParent(this);
            handlerMap.put(h.eventType(), h);
        }
    }

    /**
     * Destroys the message handler context.
     */
    public void destroy() {
        this.connection = null;
        this.directory = null;
        handlerMap.clear();
    }

    /**
     * Returns the user interface connection with which this handler was primed.
     *
     * @return user interface connection
     */
    public UiConnection connection() {
        return connection;
    }

    /**
     * Returns the user interface connection with which this handler was primed.
     *
     * @return user interface connection
     */
    public ServiceDirectory directory() {
        return directory;
    }

    /**
     * Returns implementation of the specified service class.
     *
     * @param serviceClass service class
     * @param <T>          type of service
     * @return implementation class
     * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found
     */
    protected <T> T get(Class<T> serviceClass) {
        return directory.get(serviceClass);
    }

    /**
     * Returns a freshly minted object node.
     *
     * @return new object node
     */
    protected ObjectNode objectNode() {
        return mapper.createObjectNode();
    }

    /**
     * Returns a freshly minted array node.
     *
     * @return new array node
     */
    protected ArrayNode arrayNode() {
        return mapper.createArrayNode();
    }

    /**
     * Sends the specified data to the client.
     * It is expected that the data is in the prescribed JSON format for
     * events to the client.
     *
     * @param data data to be sent
     */
    protected synchronized void sendMessage(ObjectNode data) {
        UiConnection connection = connection();
        if (connection != null) {
            connection.sendMessage(data);
        }
    }
}
