/*
 * Copyright 2015-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;

/**
 * Distributed version of com.google.common.util.concurrent.AtomicLongMap.
 */
public interface AtomicCounterMap<K> extends DistributedPrimitive {

    @Override
    default DistributedPrimitive.Type primitiveType() {
        return DistributedPrimitive.Type.COUNTER_MAP;
    }

    /**
     * Increments by one the value currently associated with key, and returns the new value.
     *
     * @param key key with which the specified value is to be associated
     * @return incremented value
     */
    long incrementAndGet(K key);

    /**
     * Decrements by one the value currently associated with key, and returns the new value.
     *
     * @param key key with which the specified value is to be associated
     * @return updated value
     */
    long decrementAndGet(K key);

    /**
     * Increments by one the value currently associated with key, and returns the old value.
     *
     * @param key key with which the specified value is to be associated
     * @return previous value
     */
    long getAndIncrement(K key);

    /**
     * Decrements by one the value currently associated with key, and returns the old value.
     *
     * @param key key with which the specified value is to be associated
     * @return previous value
     */
    long getAndDecrement(K key);

    /**
     * Adds delta to the value currently associated with key, and returns the new value.
     *
     * @param key key with which the specified value is to be associated
     * @param delta the value to add
     * @return updated value
     */
    long addAndGet(K key, long delta);

    /**
     * Adds delta to the value currently associated with key, and returns the old value.
     *
     * @param key key with which the specified value is to be associated
     * @param delta the value to add
     * @return previous value
     */
    long getAndAdd(K key, long delta);

    /**
     * Returns the value associated with key, or zero if there is no value associated with key.
     *
     * @param key key with which the specified value is to be associated
     * @return current value
     */
    long get(K key);

    /**
     * Associates ewValue with key in this map, and returns the value previously
     * associated with key, or zero if there was no such value.
     *
     * @param key key with which the specified value is to be associated
     * @param newValue the value to put
     * @return previous value or zero
     */
    long put(K key, long newValue);


    /**
     * If key is not already associated with a value or if key is associated with
     * zero, associate it with newValue. Returns the previous value associated with
     * key, or zero if there was no mapping for key.
     *
     * @param key key with which the specified value is to be associated
     * @param newValue the value to put
     * @return previous value or zero
     */
    long putIfAbsent(K key, long newValue);

    /**
     * If (key, expectedOldValue) is currently in the map, this method replaces
     * expectedOldValue with newValue and returns true; otherwise, this method return false.
     *
     * If expectedOldValue is zero, this method will succeed if (key, zero)
     * is currently in the map, or if key is not in the map at all.
     *
     * @param key key with which the specified value is to be associated
     * @param expectedOldValue the expected value
     * @param newValue the value to replace
     * @return true if the value was replaced, false otherwise
     */
    boolean replace(K key, long expectedOldValue, long newValue);

    /**
     * Removes and returns the value associated with key. If key is not
     * in the map, this method has no effect and returns zero.
     *
     * @param key key with which the specified value is to be associated
     * @return the previous value associated with the specified key or null
     */
    long remove(K key);

    /**
     * If (key, value) is currently in the map, this method removes it and returns
     * true; otherwise, this method returns false.
     *
     * @param key key with which the specified value is to be associated
     * @param value the value to remove
     * @return true if the value was removed, false otherwise
     */
    boolean remove(K key, long value);
}
