/*
 * Copyright 2016 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.store.service;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

import org.onosproject.cluster.Leadership;
import org.onosproject.cluster.NodeId;
import org.onosproject.event.Change;

/**
 * Distributed mutual exclusion primitive.
 * <p>
 * {@code AsyncLeaderElector} facilitates mutually exclusive access to a shared resource by various cluster members.
 * Each resource is identified by a unique topic name and members register their desire to access the resource by
 * calling the {@link AsyncLeaderElector#run run} method. Access is grated on a FIFO basis. An instance can
 * unregister itself from the leadership election by calling {@link AsyncLeaderElector#withdraw withdraw} method.
 * If an instance currently holding the resource dies then the next instance waiting to be leader (in FIFO order)
 * will be automatically granted access to the resource.
 * <p>
 * One can register listeners to be notified when a leadership change occurs. The Listeners are notified via a
 * {@link Leadership} {@link Change change} subject.
 * <p>
 * Additionally, {@code AsyncLeaderElector} provides methods to query the current state of leadership for topics.
 * <p>
 * All methods of this interface return a {@link CompletableFuture future} immediately after a successful invocation.
 * The operation itself is executed asynchronous and the returned future will be
 * {@link CompletableFuture#complete completed} when the operation finishes.
 */
public interface AsyncLeaderElector extends DistributedPrimitive {

    @Override
    default DistributedPrimitive.Type type() {
        return DistributedPrimitive.Type.LEADER_ELECTOR;
    }

    /**
     * Attempts to become leader for a topic.
     * @param topic leadership topic
     * @param nodeId instance identifier of the node
     * @return CompletableFuture that is completed with the current Leadership state of the topic
     */
    CompletableFuture<Leadership> run(String topic, NodeId nodeId);

    /**
     * Withdraws from leadership race for a topic.
     * @param topic leadership topic
     * @return CompletableFuture that is completed when the withdraw is done
     */
    CompletableFuture<Void> withdraw(String topic);

    /**
     * Attempts to promote a node to leadership displacing the current leader.
     * @param topic leadership topic
     * @param nodeId instance identifier of the new leader
     * @return CompletableFuture that is completed with a boolean when the operation is done. Boolean is true if
     * leadership transfer was successfully executed; false if it failed. This operation can fail (i.e. return false)
     * if the node to be made new leader is not registering to run for election for the topic.
     */
    CompletableFuture<Boolean> anoint(String topic, NodeId nodeId);

    /**
     * Returns the {@link Leadership} for the specified topic.
     * @param topic leadership topic
     * @return CompletableFuture that is completed with the current Leadership state of the topic
     */
    CompletableFuture<Leadership> getLeadership(String topic);

    /**
     * Returns the current {@link Leadership}s for all topics.
     * @return CompletableFuture that is completed with the topic to Leadership mapping
     */
    CompletableFuture<Map<String, Leadership>> getLeaderships();

    /**
     * Registers a listener to be notified of Leadership changes for all topics.
     * @param consumer listener to notify
     * @return CompletableFuture that is completed when the operation completes
     */
    CompletableFuture<Void> addChangeListener(Consumer<Change<Leadership>> consumer);

    /**
     * Unregisters a previously registered change notification listener.
     * <p>
     * If the specified listener was not previously registered, this operation will be a noop.
     * @param consumer listener to remove
     * @return CompletableFuture that is completed when the operation completes
     */
    CompletableFuture<Void> removeChangeListener(Consumer<Change<Leadership>> consumer);
}
