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

import org.onlab.util.KryoNamespace;
import org.onosproject.cluster.NodeId;

import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;

/**
 * Builder for eventually consistent maps.
 *
 * @param <K> type for map keys
 * @param <V> type for map values
 */
public interface EventuallyConsistentMapBuilder<K, V> {

    /**
     * Sets the name of the map.
     * <p>
     * Each map is identified by a string map name. EventuallyConsistentMapImpl
     * objects in different JVMs that use the same map name will form a
     * distributed map across JVMs (provided the cluster service is aware of
     * both nodes).
     * </p>
     * <p>
     * Note: This is a mandatory parameter.
     * </p>
     *
     * @param name name of the map
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withName(String name);

    /**
     * Sets a serializer builder that can be used to create a serializer that
     * can serialize both the keys and values put into the map. The serializer
     * builder should be pre-populated with any classes that will be put into
     * the map.
     * <p>
     * Note: This is a mandatory parameter.
     * </p>
     *
     * @param serializerBuilder serializer builder
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withSerializer(
            KryoNamespace.Builder serializerBuilder);

    /**
     * Sets the clock service to use for generating timestamps for map updates.
     * <p>
     * The client must provide an {@link org.onosproject.store.service.ClockService}
     * which can generate timestamps for a given key. The clock service is free
     * to generate timestamps however it wishes, however these timestamps will
     * be used to serialize updates to the map so they must be strict enough
     * to ensure updates are properly ordered for the use case (i.e. in some
     * cases wallclock time will suffice, whereas in other cases logical time
     * will be necessary).
     * </p>
     * <p>
     * Note: This is a mandatory parameter.
     * </p>
     *
     * @param clockService clock service
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withClockService(
            ClockService<K, V> clockService);

    /**
     * Sets the executor to use for processing events coming in from peers.
     *
     * @param executor event executor
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withEventExecutor(
            ExecutorService executor);

    /**
     * Sets the executor to use for sending events to peers.
     *
     * @param executor event executor
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor(
            ExecutorService executor);

    /**
     * Sets the executor to use for background anti-entropy tasks.
     *
     * @param executor event executor
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withBackgroundExecutor(
            ScheduledExecutorService executor);

    /**
     * Sets a function that can determine which peers to replicate updates to.
     * <p>
     * The default function replicates to all nodes.
     * </p>
     *
     * @param peerUpdateFunction function that takes a K, V input and returns
     *                           a collection of NodeIds to replicate the event
     *                           to
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withPeerUpdateFunction(
            BiFunction<K, V, Collection<NodeId>> peerUpdateFunction);

    /**
     * Prevents this map from writing tombstones of items that have been
     * removed. This may result in zombie items reappearing after they have
     * been removed.
     * <p>
     * The default behavior is tombstones are enabled.
     * </p>
     *
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled();

    /**
     * Configures how often to run the anti-entropy background task.
     * <p>
     * The default anti-entropy period is 5 seconds.
     * </p>
     *
     * @param period anti-entropy period
     * @param unit time unit for the period
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod(
            long period, TimeUnit unit);

    /**
     * Configure anti-entropy to converge faster at the cost of doing more work
     * for each anti-entropy cycle. Suited to maps with low update rate where
     * convergence time is more important than throughput.
     * <p>
     * The default behavior is to do less anti-entropy work at the cost of
     * slower convergence.
     * </p>
     *
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withFasterConvergence();

    /**
     * Configure the map to persist data to disk.
     * <p>
     * The default behavior is no persistence
     * </p>
     *
     * @return this EventuallyConsistentMapBuilder
     */
    public EventuallyConsistentMapBuilder<K, V> withPersistence();

    /**
     * Builds an eventually consistent map based on the configuration options
     * supplied to this builder.
     *
     * @return new eventually consistent map
     * @throws java.lang.RuntimeException if a mandatory parameter is missing
     */
    public EventuallyConsistentMap<K, V> build();
}
