package org.apache.helix;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import java.util.List;
import java.util.Map;

import org.apache.helix.messaging.AsyncCallback;
import org.apache.helix.messaging.handling.MessageHandlerFactory;
import org.apache.helix.model.Message;

/**
 * Provides the ability to <br>
 * <li>Send message to a specific component in the cluster[ participant, controller,
 * Spectator(probably not needed) ]</li> <li>Broadcast message to all participants</li> <li>Send
 * message to instances that hold a specific resource</li> <li>Asynchronous request response api.
 * Send message with a co-relation id and invoke a method when there is a response. Can support
 * timeout.</li>
 */
public interface ClusterMessagingService {
  /**
   * Send message matching the specifications mentioned in recipientCriteria.
   * @param recipientCriteria criteria to be met, defined as {@link Criteria}
   * @See Criteria
   * @param message
   *          message to be sent. Some attributes of this message will be
   *          changed as required
   * @return the number of messages that were successfully sent.
   */
  int send(Criteria recipientCriteria, Message message);

  /**
   * This will send the message to all instances matching the criteria<br>
   * When there is a reply to the message sent AsyncCallback.onReply will be
   * invoked. Application can specify a timeout on AsyncCallback. After every
   * reply is processed AsyncCallback.isDone will be invoked.<br>
   * This method will return after sending the messages. <br>
   * This is useful when message need to be sent and current thread need not
   * wait for response since processing will be done in another thread.
   * @see #send(Criteria, Message)
   * @param recipientCriteria
   * @param message
   * @param callbackOnReply callback to trigger on completion
   * @param timeOut Time to wait before failing the send
   * @return the number of messages that were successfully sent
   */
  int send(Criteria recipientCriteria, Message message, AsyncCallback callbackOnReply, int timeOut);

  /**
   * @see #send(Criteria, Message, AsyncCallback, int)
   * @param recipientCriteria
   * @param message
   * @param callbackOnReply
   * @param timeOut
   * @param retryCount maximum number of times to retry the send
   * @return the number of messages that were successfully sent
   */
  int send(Criteria recipientCriteria, Message message, AsyncCallback callbackOnReply,
      int timeOut, int retryCount);

  /**
   * This will send the message to all instances matching the criteria<br>
   * When there is a reply to the message sent AsynCallback.onReply will be
   * invoked. Application can specify a timeout on AsyncCallback. After every
   * reply is processed AsyncCallback.isDone will be invoked.<br>
   * This method will return only after the AsyncCallback.isDone() returns true <br>
   * This is useful when message need to be sent and current thread has to wait
   * for response. <br>
   * The current thread can use callbackOnReply instance to store application
   * specific data.
   * @see #send(Criteria, Message, AsyncCallback, int)
   * @param recipientCriteria
   * @param message
   * @param callbackOnReply
   * @param timeOut
   * @return the number of messages that were successfully sent
   */
  int sendAndWait(Criteria recipientCriteria, Message message, AsyncCallback callbackOnReply,
      int timeOut);

  /**
   * @see #send(Criteria, Message, AsyncCallback, int, int)
   * @param receipientCriteria
   * @param message
   * @param callbackOnReply
   * @param timeOut
   * @param retryCount
   * @return the number of messages that were successfully sent
   */
  int sendAndWait(Criteria receipientCriteria, Message message, AsyncCallback callbackOnReply,
      int timeOut, int retryCount);

  /**
   * This will register a message handler factory to create handlers for
   * message. In case client code defines its own message type, it can define a
   * message handler factory to create handlers to process those messages.
   * Messages are processed in a threadpool which is hosted by cluster manager,
   * and cluster manager will call the factory to create handler, and the
   * handler is called in the threadpool.
   * Note that only one message handler factory can be registered with one
   * message type.
   * @param type
   *          The message type that the factory will create handler for
   * @param factory
   *          The per-type message factory
   */
  public void registerMessageHandlerFactory(String type, MessageHandlerFactory factory);


  /**
   * This will register a message handler factory to create handlers for
   * message. In case client code defines its own message type, it can define a
   * message handler factory to create handlers to process those messages.
   * Messages are processed in a threadpool which is hosted by cluster manager,
   * and cluster manager will call the factory to create handler, and the
   * handler is called in the threadpool.
   * Note that only one message handler factory can be registered with one
   * message type.
   * @param types
   *          The different message types that the factory will create handler for
   * @param factory
   *          The per-type message factory
   */
  public void registerMessageHandlerFactory(List<String> types, MessageHandlerFactory factory);

  /**
   * This will generate all messages to be sent given the recipientCriteria and MessageTemplate,
   * the messages are not sent.
   * @param recipientCriteria criteria to be met, defined as {@link Criteria}
   * @param messageTemplate the Message on which to base the messages to send
   * @return messages to be sent, grouped by the type of instance to send the message to
   */
  public Map<InstanceType, List<Message>> generateMessage(final Criteria recipientCriteria,
      final Message messageTemplate);

}
