/*
 * 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.consistent.impl;

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

import org.onosproject.cluster.NodeId;
import org.onosproject.store.service.Transaction;
import org.onosproject.store.service.Versioned;

/**
 * Database proxy.
 */
public interface DatabaseProxy<K, V> {

    /**
     * Returns a set of all map names.
     *
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Set<String>> maps();

    /**
     * Returns a mapping from counter name to next value.
     *
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Map<String, Long>> counters();

    /**
     * Returns the number of entries in map.
     * @param mapName map name
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Integer> mapSize(String mapName);

    /**
     * Checks whether the map is empty.
     *
     * @param mapName map name
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Boolean> mapIsEmpty(String mapName);

    /**
     * Checks whether the map contains a key.
     *
     * @param mapName map name
     * @param key key to check.
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Boolean> mapContainsKey(String mapName, K key);

    /**
     * Checks whether the map contains a value.
     *
     * @param mapName map name
     * @param value The value to check.
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Boolean> mapContainsValue(String mapName, V value);

    /**
     * Gets a value from the map.
     *
     * @param mapName map name
     * @param key The key to get.
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Versioned<V>> mapGet(String mapName, K key);

    /**
     * Updates the map.
     *
     * @param mapName map name
     * @param key           The key to set
     * @param valueMatch    match for checking existing value
     * @param versionMatch  match for checking existing version
     * @param value         new value
     * @return A completable future to be completed with the result once complete
     */
    CompletableFuture<Result<UpdateResult<K, V>>> mapUpdate(
            String mapName, K key, Match<V> valueMatch, Match<Long> versionMatch, V value);

    /**
     * Clears the map.
     *
     * @param mapName map name
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Result<Void>> mapClear(String mapName);

    /**
     * Gets a set of keys in the map.
     *
     * @param mapName map name
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Set<K>> mapKeySet(String mapName);

    /**
     * Gets a collection of values in the map.
     *
     * @param mapName map name
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Collection<Versioned<V>>> mapValues(String mapName);

    /**
     * Gets a set of entries in the map.
     *
     * @param mapName map name
     * @return A completable future to be completed with the result once complete.
     */
    CompletableFuture<Set<Map.Entry<K, Versioned<V>>>> mapEntrySet(String mapName);

     /**
     * Atomically add the given value to current value of the specified counter.
     *
     * @param counterName counter name
     * @param delta value to add
     * @return updated value
     */
    CompletableFuture<Long> counterAddAndGet(String counterName, long delta);

    /**
     * Atomically add the given value to current value of the specified counter.
     *
     * @param counterName counter name
     * @param delta value to add
     * @return previous value
     */
    CompletableFuture<Long> counterGetAndAdd(String counterName, long delta);

    /**
     * Returns the current value of the specified atomic counter.
     *
     * @param counterName counter name
     * @return current value
     */
    CompletableFuture<Long> counterGet(String counterName);

    /**
     * Returns the size of queue.
     * @param queueName queue name
     * @return queue size
     */
    CompletableFuture<Long> queueSize(String queueName);

    /**
     * Inserts an entry into the queue.
     * @param queueName queue name
     * @param entry queue entry
     * @return set of nodes to notify about the queue update
     */
    CompletableFuture<Set<NodeId>> queuePush(String queueName, byte[] entry);

    /**
     * Removes an entry from the queue if the queue is non-empty.
     * @param queueName queue name
     * @param nodeId If the queue is empty the identifier of node to notify when an entry becomes available
     * @return entry. Can be null if queue is empty
     */
    CompletableFuture<byte[]> queuePop(String queueName, NodeId nodeId);

    /**
     * Returns but does not remove an entry from the queue.
     * @param queueName queue name
     * @return entry. Can be null if queue is empty
     */
    CompletableFuture<byte[]> queuePeek(String queueName);

    /**
     * Prepare and commit the specified transaction.
     *
     * @param transaction transaction to commit (after preparation)
     * @return A completable future to be completed with the result once complete
     */
    CompletableFuture<CommitResponse> prepareAndCommit(Transaction transaction);

    /**
     * Prepare the specified transaction for commit. A successful prepare implies
     * all the affected resources are locked thus ensuring no concurrent updates can interfere.
     *
     * @param transaction transaction to prepare (for commit)
     * @return A completable future to be completed with the result once complete. The future is completed
     * with true if the transaction is successfully prepared i.e. all pre-conditions are met and
     * applicable resources locked.
     */
    CompletableFuture<Boolean> prepare(Transaction transaction);

    /**
     * Commit the specified transaction. A successful commit implies
     * all the updates are applied, are now durable and are now visible externally.
     *
     * @param transaction transaction to commit
     * @return A completable future to be completed with the result once complete
     */
    CompletableFuture<CommitResponse> commit(Transaction transaction);

    /**
     * Rollback the specified transaction. A successful rollback implies
     * all previously acquired locks for the affected resources are released.
     *
     * @param transaction transaction to rollback
     * @return A completable future to be completed with the result once complete
     */
    CompletableFuture<Boolean> rollback(Transaction transaction);
}
