/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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 com.google.common.util.concurrent.MoreExecutors;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 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, Iterable<Map.Entry<K, V>> {
    /**
     * 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);

    /**
     * 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 the updated value, 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 the updated values
     */
    Versioned<Collection<? extends V>> putAndGet(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 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 the updated values
     */
    Versioned<Collection<? extends V>> removeAndGet(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);

    /**
     * Removes the set of 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 mapping the keys-values to be removed
     * @return true if the map changes because of this call, false otherwise.
     */
    boolean removeAll(Map<K, Collection<? extends V>> mapping);

    /**
     * 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);

    /**
     * Adds the set of key-value pairs of the specified mapping 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 mapping the keys-values to be added
     * @return true if any change in the map results from this call,
     * false otherwise
     */
    boolean putAll(Map<K, Collection<? extends V>> mapping);

    /**
     * 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.
     * <p>
     * Do not use this method to read large maps. Use an {@link #iterator()} or {@link #stream()} instead.
     *
     * @return a collection of all entries in the map, this may be empty
     */
    Collection<Map.Entry<K, V>> entries();

    /**
     * Streams entries from the map.
     * <p>
     * This method is optimized for large maps.
     *
     * @return the map entry stream
     */
    default Stream<Map.Entry<K, V>> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    /**
     * 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();

    /**
     * Registers the specified listener to be notified whenever the map is updated.
     *
     * @param listener listener to notify about map events
     */
    default void addListener(MultimapEventListener<K, V> listener) {
        addListener(listener, MoreExecutors.directExecutor());
    }

    /**
     * Registers the specified listener to be notified whenever the map is updated.
     *
     * @param listener listener to notify about map events
     * @param executor executor to use for handling incoming map events
     */
    void addListener(MultimapEventListener<K, V> listener, Executor executor);

    /**
     * Unregisters the specified listener such that it will no longer
     * receive map change notifications.
     *
     * @param listener listener to unregister
     */
    void removeListener(MultimapEventListener<K, V> listener);
}
