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

import java.util.Collection;
import java.util.Optional;

import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.InnerNode;
import org.onosproject.yang.model.NodeKey;
import org.onosproject.yang.model.SchemaId;

import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;

/**
 * Utility related to DataNode.
 */
@Beta
public abstract class DataNodes {

    // TODO it might make sense to turn these into DataNode methods

    // should avoid using this. use other child methods
    @Deprecated
    public static Optional<DataNode> childOnlyByName(DataNode node, String name) {
        if (node instanceof InnerNode) {
            InnerNode inode = (InnerNode) node;
            return inode.childNodes().values().stream()
                        .filter(dn -> dn.key().schemaId().name().equals(name))
                        .findFirst();
        } else {
            return Optional.empty();
        }
    }

    public static Optional<DataNode> child(DataNode node, String name, String namespace) {
        if (node instanceof InnerNode) {
            InnerNode inode = (InnerNode) node;
            NodeKey<?> key = NodeKey.builder().schemaId(name, namespace).build();
            return Optional.ofNullable(inode.childNodes().get(key));
        } else {
            return Optional.empty();
        }
    }

    public static Optional<DataNode> child(DataNode node, SchemaId child) {
        if (node instanceof InnerNode) {
            InnerNode inode = (InnerNode) node;
            NodeKey<?> key = NodeKey.builder().schemaId(child).build();
            return Optional.ofNullable(inode.childNodes().get(key));
        } else {
            return Optional.empty();
        }
    }

    public static Optional<DataNode> child(DataNode node, NodeKey<?> child) {
        if (node instanceof InnerNode) {
            InnerNode inode = (InnerNode) node;
            return Optional.ofNullable(inode.childNodes().get(child));
        } else {
            return Optional.empty();
        }
    }

    public static Collection<DataNode> children(DataNode node) {
        if (node instanceof InnerNode) {
            InnerNode inode = (InnerNode) node;
            return inode.childNodes().values();
        } else {
            return ImmutableList.of();
        }
    }

}
