/*
 * 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 org.onosproject.store.primitives.DefaultConsistentTreeMap;

import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.concurrent.CompletableFuture;

import static org.onosproject.store.service.DistributedPrimitive.DEFAULT_OPERTATION_TIMEOUT_MILLIS;

/**
 * API for a distributed tree map implementation.
 */
public interface AsyncConsistentTreeMap<V>
        extends AsyncConsistentMap<String, V> {

    /**
     * Return the lowest key in the map.
     *
     * @return the key or null if none exist
     */
    CompletableFuture<String> firstKey();

    /**
     * Return the highest key in the map.
     *
     * @return the key or null if none exist
     */
    CompletableFuture<String> lastKey();

    /**
     * Returns the entry associated with the least key greater than or equal to
     * the key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> ceilingEntry(
            String key);

    /**
     * Returns the entry associated with the greatest key less than or equal
     * to key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> floorEntry(String key);

    /**
     * Returns the entry associated with the least key greater than key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> higherEntry(String key);

    /**
     * Returns the entry associated with the largest key less than key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> lowerEntry(String key);

    /**
     * Return the entry associated with the lowest key in the map.
     *
     * @return the entry or null if none exist
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> firstEntry();

    /**
     * Return the entry associated with the highest key in the map.
     *
     * @return the entry or null if none exist
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> lastEntry();

    /**
     * Return and remove the entry associated with the lowest key.
     *
     * @return the entry or null if none exist
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> pollFirstEntry();

    /**
     * Return and remove the entry associated with the highest key.
     *
     * @return the entry or null if none exist
     */
    CompletableFuture<Map.Entry<String, Versioned<V>>> pollLastEntry();

    /**
     * Return the entry associated with the greatest key less than key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<String> lowerKey(String key);

    /**
     * Return the highest key less than or equal to key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<String> floorKey(String key);

    /**
     * Return the lowest key greater than or equal to key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<String> ceilingKey(String key);

    /**
     * Return the lowest key greater than key.
     *
     * @param key the key
     * @return the entry or null if no suitable key exists
     */
    CompletableFuture<String> higherKey(String key);

    /**
     * Returns a navigable set of the keys in this map.
     *
     * @return a navigable key set (this may be empty)
     */
    CompletableFuture<NavigableSet<String>> navigableKeySet();

    /**
     * Returns a navigable map containing the entries from the original map
     * which are larger than (or if specified equal to) {@code lowerKey} AND
     * less than (or if specified equal to) {@code upperKey}.
     *
     * @param upperKey the upper bound for the keys in this map
     * @param lowerKey the lower bound for the keys in this map
     * @param inclusiveUpper whether keys equal to the upperKey should be
     *                       included
     * @param inclusiveLower whether keys equal to the lowerKey should be
     *                       included
     * @return a navigable map containing entries in the specified range (this
     * may be empty)
     */
    CompletableFuture<NavigableMap<String, V>> subMap(String upperKey,
                                                      String lowerKey,
                                                      boolean inclusiveUpper,
                                                      boolean inclusiveLower);

    default ConsistentTreeMap<V> asTreeMap() {
        return asTreeMap(DEFAULT_OPERTATION_TIMEOUT_MILLIS);
    }

    default ConsistentTreeMap<V> asTreeMap(long timeoutMillis) {
        return new DefaultConsistentTreeMap<>(this, timeoutMillis);
    }


}
