/*
 * Copyright 2017-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.store.cluster.messaging;

import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
import java.util.function.Function;

import org.onosproject.cluster.NodeId;

/**
 * Service for assisting communications between controller cluster nodes.
 */
public interface ClusterCommunicator {

    /**
     * Adds a new subscriber for the specified message subject.
     *
     * @param subject    message subject
     * @param subscriber message subscriber
     * @param executor executor to use for running handler.
     * @deprecated in Cardinal Release
     */
    @Deprecated
    void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber, ExecutorService executor);

    /**
     * Broadcasts a message to all controller nodes.
     *
     * @param message message to send
     * @param subject message subject
     * @param encoder function for encoding message to byte[]
     * @param <M> message type
     */
    <M> void broadcast(M message,
            MessageSubject subject,
            Function<M, byte[]> encoder);

    /**
     * Broadcasts a message to all controller nodes including self.
     *
     * @param message message to send
     * @param subject message subject
     * @param encoder function for encoding message to byte[]
     * @param <M> message type
     */
    <M> void broadcastIncludeSelf(M message,
            MessageSubject subject,
            Function<M, byte[]> encoder);

    /**
     * Sends a message to the specified controller node.
     *
     * @param message message to send
     * @param subject message subject
     * @param encoder function for encoding message to byte[]
     * @param toNodeId destination node identifier
     * @param <M> message type
     * @return future that is completed when the message is sent
     */
    <M> CompletableFuture<Void> unicast(M message,
            MessageSubject subject,
            Function<M, byte[]> encoder,
            NodeId toNodeId);

    /**
     * Multicasts a message to a set of controller nodes.
     *
     * @param message message to send
     * @param subject message subject
     * @param encoder function for encoding message to byte[]
     * @param nodeIds  recipient node identifiers
     * @param <M> message type
     */
    <M> void multicast(M message,
            MessageSubject subject,
            Function<M, byte[]> encoder,
            Set<NodeId> nodeIds);

    /**
     * Sends a message and expects a reply.
     *
     * @param message message to send
     * @param subject message subject
     * @param encoder function for encoding request to byte[]
     * @param decoder function for decoding response from byte[]
     * @param toNodeId recipient node identifier
     * @param <M> request type
     * @param <R> reply type
     * @return reply future
     */
    <M, R> CompletableFuture<R> sendAndReceive(M message,
            MessageSubject subject,
            Function<M, byte[]> encoder,
            Function<byte[], R> decoder,
            NodeId toNodeId);

    /**
     * Adds a new subscriber for the specified message subject.
     *
     * @param subject message subject
     * @param decoder decoder for resurrecting incoming message
     * @param handler handler function that processes the incoming message and produces a reply
     * @param encoder encoder for serializing reply
     * @param executor executor to run this handler on
     * @param <M> incoming message type
     * @param <R> reply message type
     */
    <M, R> void addSubscriber(MessageSubject subject,
            Function<byte[], M> decoder,
            Function<M, R> handler,
            Function<R, byte[]> encoder,
            Executor executor);

    /**
     * Adds a new subscriber for the specified message subject.
     *
     * @param subject message subject
     * @param decoder decoder for resurrecting incoming message
     * @param handler handler function that processes the incoming message and produces a reply
     * @param encoder encoder for serializing reply
     * @param <M> incoming message type
     * @param <R> reply message type
     */
    <M, R> void addSubscriber(MessageSubject subject,
            Function<byte[], M> decoder,
            Function<M, CompletableFuture<R>> handler,
            Function<R, byte[]> encoder);

    /**
     * Adds a new subscriber for the specified message subject.
     *
     * @param subject message subject
     * @param decoder decoder to resurrecting incoming message
     * @param handler handler for handling message
     * @param executor executor to run this handler on
     * @param <M> incoming message type
     */
    <M> void addSubscriber(MessageSubject subject,
            Function<byte[], M> decoder,
            Consumer<M> handler,
            Executor executor);

    /**
     * Removes a subscriber for the specified message subject.
     *
     * @param subject message subject
     */
    void removeSubscriber(MessageSubject subject);
}
