/*
 * 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 java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * A distributed, eventually consistent map.
 * <p>
 * This map does not offer read after writes consistency. Operations are
 * serialized via the timestamps issued by the clock service. If two updates
 * are in conflict, the update with the more recent timestamp will endure.
 * </p><p>
 * The interface is mostly similar to {@link java.util.Map} with some minor
 * semantic changes and the addition of a listener framework (because the map
 * can be mutated by clients on other instances, not only through the local Java
 * API).
 * </p><p>
 * Clients are expected to register an
 * {@link EventuallyConsistentMapListener} if they
 * are interested in receiving notifications of update to the map.
 * </p><p>
 * Null values are not allowed in this map.
 * </p>
 */
public interface EventuallyConsistentMap<K, V> {

    /**
     * Returns the number of key-value mappings in this map.
     *
     * @return number of key-value mappings
     */
    int size();

    /**
     * Returns true if this map is empty.
     *
     * @return true if this map is empty, otherwise false
     */
    boolean isEmpty();

    /**
     * Returns true if the map contains a mapping for the specified key.
     *
     * @param key the key to check if this map contains
     * @return true if this map has a mapping for the key, otherwise false
     */
    boolean containsKey(K key);

    /**
     * Returns true if the map contains a mapping from any key to the specified
     * value.
     *
     * @param value the value to check if this map has a mapping for
     * @return true if this map has a mapping to this value, otherwise false
     */
    boolean containsValue(V value);

    /**
     * Returns the value mapped to the specified key.
     *
     * @param key the key to look up in this map
     * @return the value mapped to the key, or null if no mapping is found
     */
    V get(K key);

    /**
     * Associates the specified value to the specified key in this map.
     * <p>
     * Note: this differs from the specification of {@link java.util.Map}
     * because it does not return the previous value associated with the key.
     * Clients are expected to register an
     * {@link EventuallyConsistentMapListener} if
     * they are interested in receiving notification of updates to the map.
     * </p><p>
     * Null values are not allowed in the map.
     * </p>
     *
     * @param key the key to add a mapping for in this map
     * @param value the value to associate with the key in this map
     */
    void put(K key, V value);

    /**
     * Removes the mapping associated with the specified key from the map.
     * <p>
     * Note: this differs from the specification of {@link java.util.Map}
     * because it does not return the previous value associated with the key.
     * Clients are expected to register an
     * {@link EventuallyConsistentMapListener} if
     * they are interested in receiving notification of updates to the map.
     * </p>
     *
     * @param key the key to remove the mapping for
     */
    void remove(K key);

    /**
     * Removes the given key-value mapping from the map, if it exists.
     * <p>
     * This actually means remove any values up to and including the timestamp
     * given by {@link org.onosproject.store.service.ClockService#getTimestamp(Object, Object)}.
     * Any mappings that produce an earlier timestamp than this given key-value
     * pair will be removed, and any mappings that produce a later timestamp
     * will supersede this remove.
     * </p><p>
     * Note: this differs from the specification of {@link java.util.Map}
     * because it does not return a boolean indication whether a value was removed.
     * Clients are expected to register an
     * {@link EventuallyConsistentMapListener} if
     * they are interested in receiving notification of updates to the map.
     * </p>
     *
     * @param key the key to remove the mapping for
     * @param value the value mapped to the key
     */
    void remove(K key, V value);

    /**
     * Adds mappings for all key-value pairs in the specified map to this map.
     * <p>
     * This will be more efficient in communication than calling individual put
     * operations.
     * </p>
     *
     * @param m a map of values to add to this map
     */
    void putAll(Map<? extends K, ? extends V> m);

    /**
     * Removes all mappings from this map.
     */
    void clear();

    /**
     * Returns a set of the keys in this map. Changes to the set are not
     * reflected back to the map.
     *
     * @return set of keys in the map
     */
    Set<K> keySet();

    /**
     * Returns a collections of values in this map. Changes to the collection
     * are not reflected back to the map.
     *
     * @return collection of values in the map
     */
    Collection<V> values();

    /**
     * Returns a set of mappings contained in this map. Changes to the set are
     * not reflected back to the map.
     *
     * @return set of key-value mappings in this map
     */
    Set<Map.Entry<K, V>> entrySet();

    /**
     * Adds the specified listener to the map which will be notified whenever
     * the mappings in the map are changed.
     *
     * @param listener listener to register for events
     */
    void addListener(EventuallyConsistentMapListener<K, V> listener);

    /**
     * Removes the specified listener from the map such that it will no longer
     * receive change notifications.
     *
     * @param listener listener to deregister for events
     */
    void removeListener(EventuallyConsistentMapListener<K, V> listener);

    /**
     * Shuts down the map and breaks communication between different instances.
     * This allows the map objects to be cleaned up and garbage collected.
     * Calls to any methods on the map subsequent to calling destroy() will
     * throw a {@link java.lang.RuntimeException}.
     */
    void destroy();
}
