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

import com.google.common.annotations.Beta;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.store.Store;

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

/**
 * Store interface for storing and distributing dynamic configuration data.
 */
@Beta
public interface DynamicConfigStore
        extends Store<DynamicConfigEvent, DynamicConfigStoreDelegate> {
    /**
     * Adds a new node in the dynamic config store. The new node will not be
     * added if there is a node with the same identifier, already present at
     * the specified path or any of the parent nodes were not present in the
     * path leading up to the requested node.
     *
     * @param path data structure with absolute path to the parent
     * @param node recursive data structure, holding a leaf node or a subtree
     * @return future that is completed with {@code true} if the new node was
     * successfully added or completed exceptionally with
     * {@code FailedException} if node addition failed
     */
    CompletableFuture<Boolean> addNode(ResourceId path, DataNode node);

    /**
     * Adds a new node in the dynamic config store.
     * Creates any missing parent nodes, leading up to the given node. Node
     * will not be added if there is a node with the same identifier, already
     * present at the specified path.
     *
     * @param path data structure with absolute path to the parent
     * @param node recursive data structure, holding a leaf node or a subtree
     * @return future that is completed with {@code true} if the node was
     * successfully added or completed exceptionally with
     * {@code FailedException} if the node addition failed
     */
    CompletableFuture<Boolean> addRecursive(ResourceId path, DataNode node);

    /**
     * Reads the requested node from the dynamic config store.
     * This operation would get translated to reading a leaf node or a subtree.
     * This would fail if the requested node was not present or any parent nodes
     * in the path were not present.
     *
     * @param path data structure with absolute path to the intended node
     * @param filter filtering conditions to be applied on the result list of nodes
     * @return future that will be completed with a DataNode (will be an empty
     * DataNode if after applying the filter, the result is an empty list of nodes)
     * or completed with {@code FailedException} if the node could not be read
     */
    CompletableFuture<DataNode> readNode(ResourceId path, Filter filter);

    /**
     * Updates an existing node in the dynamic config store.
     * This request would fail if the requested node, any of its children or
     * any parent nodes in the path were not present.
     *
     * @param path data structure with absolute path to the parent
     * @param node recursive data structure, holding a leaf node or a subtree
     * @return future that is completed with {@code true} if the node was
     * successfully updated or completed exceptionally with
     * {@code FailedException} if the update request failed
     */
    CompletableFuture<Boolean> updateNode(ResourceId path, DataNode node);

    /**
     * Updates an existing node in the dynamic config store.
     * Any missing children will be created with this request. The update will
     * fail if the requested node or any of the parent nodes in the path
     * were not present.
     *
     * @param path data structure with absolute path to the parent
     * @param node recursive data structure, holding a leaf node or a subtree
     * @return future that is completed with {@code true} if the node was
     * successfully updated or completed exceptionally with
     * {@code FailedException} if the update request failed
     */
    CompletableFuture<Boolean> updateNodeRecursive(ResourceId path, DataNode node);

    /**
     * Replaces nodes in the dynamic config store.
     * This will ensure that only the tree structure in the given DataNode will
     * be in place after a replace. This would fail if the requested node or
     * any of the parent nodes in the path were not present.
     *
     * @param path data structure with absolute path to the parent
     * @param node recursive data structure, holding a leaf node or a subtree
     * @return future that is completed with {@code true} if the node was
     * successfully replaced or completed exceptionally with
     * {@code FailedException} if the replace request failed
     */
    CompletableFuture<Boolean> replaceNode(ResourceId path, DataNode node);

    /**
     * Removes  a node from the dynamic config store.
     * This would fail if the requested node or any of the parent nodes in the
     * path were not present or the specified node is the root node or has one
     * or more children.
     *
     * @param path data structure with absolute path to the intended node
     * @return future that is completed with {@code true} if the node was
     * successfully deleted or completed exceptionally with
     * {@code FailedException} if the delete request failed
     */
    CompletableFuture<Boolean> deleteNode(ResourceId path);

    /**
     * Removes a subtree from the dynamic config store.
     * This will delete all the children recursively, under the given node.
     * Will fail if the requested node or any of the parent nodes in
     * the path were not present.
     *
     * @param path data structure with absolute path to the intended node
     * @return future that is completed with {@code true} if the delete was
     * successful or completed exceptionally with
     * {@code FailedException} if the delete request failed
     */
    CompletableFuture<Boolean> deleteNodeRecursive(ResourceId path);

    /**
     * Adds a listener to be notified when a leaf or subtree rooted at the
     * specified path is modified.
     *
     * @param path data structure with absolute path to the node being listened to
     * @param listener listener to be notified
     * @throws FailedException if the listener could not be added
     */
    void addConfigListener(ResourceId path, DynamicConfigListener listener);

    /**
     * Removes a previously added listener.
     *
     * @param path data structure with absolute path to the node being listened to
     * @param listener listener to unregister
     * @throws FailedException if the listener could not be removed
     */
    void removeConfigListener(ResourceId path, DynamicConfigListener listener);

    /**
     * Returns a collection of previously added listeners.
     *
     * @param path data structure with absolute path to the node being listened to
     * @return  a collection of previously added listeners
     */
    Collection<? extends DynamicConfigListener> getConfigListener(ResourceId path);
    //DynamicConfigListener getConfigListener(ResourceId path);
}