/*
 * Copyright 2016-present 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 com.google.common.collect.Multiset;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * This provides a synchronous version of the functionality provided by
 * {@link AsyncConsistentMultimap}.  Instead of returning futures this map
 * blocks until the future completes then returns the result.
 */
public interface ConsistentMultimap<K, V> extends DistributedPrimitive {
    /**
     * Returns the number of key-value pairs in this multimap.
     * @return the number of key-value pairs
     */
    int size();

    /**
     * Returns if this multimap contains no key-value pairs.
     *
     * @return true if no key-value pairs exist, false otherwise
     */
    boolean isEmpty();

    /**
     * Returns true if there is at lease one key-value pair with a key equal to
     * key.
     *
     * @param key the key to query
     * @return true if the map contains a
     * key-value pair with key false otherwise
     */
    boolean containsKey(K key);

    /**
     * Returns true if this map contains at lease one key-value pair with a
     * value equal to value.
     *
     * @param value the value to query
     * @return true if there is a key-value pair with the specified value,
     * false otherwise.
     */
    boolean containsValue(V value);

    /**
     * Returns true if this map contains at least one key-value pair with key
     * and value specified.
     *
     * @param key the key to query
     * @param value the value to query
     * @return true if there is a key-value pair with the specified key and
     * value, false otherwise.
     */
    boolean containsEntry(K key, V value);

    /**
     * If the key-value pair does not already exist adds either the key value
     * pair or the value to the set of values associated with the key and
     * returns true, if the key-value pair already exists then behavior is
     * implementation specific with some implementations allowing duplicates
     * and others ignoring put requests for existing entries.
     *
     * @param key the key to add
     * @param value the value to add
     * @return true if the map has changed because of this call,
     * false otherwise
     */
    boolean put(K key, V value);

    /**
     * Removes the key-value pair with the specified values if it exists. In
     * implementations that allow duplicates which matching entry will be
     * removed is undefined.
     *
     * @param key the key of the pair to be removed
     * @param value the value of the pair to be removed
     * @return true if the map changed because of this call, false otherwise.
     */
    boolean remove(K key, V value);

    /**
     * Removes the key-value pairs with the specified key and values if they
     * exist. In implementations that allow duplicates each instance of a key
     * will remove one matching entry, which one is not defined. Equivalent to
     * repeated calls to {@code remove()} for each key value pair but more
     * efficient.
     *
     * @param key the key of the pair to be removed
     * @param values the set of values to be removed
     * @return true if the map changes because of this call, false otherwise.
     */
    boolean removeAll(K key, Collection<? extends V> values);

    /**
     * Removes all values associated with the specified key as well as the key
     * itself.
     *
     * @param key the key whose key-value pairs will be removed
     * @return the set of values that were removed, which may be empty, if the
     * values did not exist the version will be less than one.
     */
    Versioned<Collection<? extends V>> removeAll(K key);

    /**
     * Adds the set of key-value pairs of the specified key with each of the
     * values in the iterable if each key-value pair does not already exist,
     * if the pair does exist the behavior is implementation specific.
     * (Same as repeated puts but with efficiency gains.)
     *
     * @param key the key to use for all pairs to be added
     * @param values the set of values to be added in pairs with the key
     * @return true if any change in the map results from this call,
     * false otherwise
     */
    boolean putAll(K key, Collection<? extends V> values);

    /**
     * Stores all the values in values associated with the key specified,
     * removes all preexisting values and returns a collection of the removed
     * values which may be empty if the entry did not exist.
     *
     * @param key the key for all entries to be added
     * @param values the values to be associated with the key
     * @return the collection of removed values, which may be empty
     */
    Versioned<Collection<? extends V>> replaceValues(K key,
                                                     Collection<V> values);

    /**
     * Removes all key-value pairs, after which it will be empty.
     */
    void clear();

    /**
     * Returns a collection of values associated with the specified key, if the
     * key is not in the map it will return an empty collection.
     *
     * @param key the key whose associated values will be returned
     * @return the collection of the values
     * associated with the specified key, the collection may be empty
     */
    Versioned<Collection<? extends V>> get(K key);

    /**
     * Returns a set of the keys contained in this multimap with one or more
     * associated values.
     *
     * @return the collection of all keys with one or more associated values,
     * this may be empty
     */
    Set<K> keySet();

    /**
     * Returns a multiset of the keys present in this multimap with one or more
     * associated values each. Keys will appear once for each key-value pair
     * in which they participate.
     *
     * @return a multiset of the keys, this may be empty
     */
    Multiset<K> keys();

    /**
     * Returns a collection of values in the set with duplicates permitted, the
     * size of this collection will equal the size of the map at the time of
     * creation.
     *
     * @return a collection of values, this may be empty
     */
    Multiset<V> values();

    /**
     * Returns a collection of each key-value pair in this map.
     *
     * @return a collection of all entries in the map, this may be empty
     */
    Collection<Map.Entry<K, V>> entries();

    /**
     * Returns a map of keys to collections of values that reflect the set of
     * key-value pairs contained in the multimap, where the key value pairs
     * would be the key paired with each of the values in the collection.
     *
     * @return a map of keys to collections of values, the returned map may be
     * empty.
     */
    Map<K, Collection<V>> asMap();
}
