/*
 * 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 static com.google.common.base.Preconditions.checkArgument;
import static org.slf4j.LoggerFactory.getLogger;

import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.KeyLeaf;
import org.onosproject.yang.model.LeafListKey;
import org.onosproject.yang.model.ListKey;
import org.onosproject.yang.model.NodeKey;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.model.ResourceId.Builder;
import org.onosproject.yang.model.SchemaId;
import org.slf4j.Logger;

import com.google.common.annotations.Beta;

/**
 * Utility related to ResourceId.
 */
@Beta
public abstract class ResourceIds {

    private static final Logger log = getLogger(ResourceIds.class);

    /**
     * Builds the ResourceId of specified {@code node}.
     *
     * @param parent ResourceId of {@code node} parent
     * @param node to create ResourceId.
     * @return ResourceId of {@code node}
     */
    public static ResourceId resourceId(ResourceId parent, DataNode node) {
        final ResourceId.Builder builder;
        if (parent == null) {
            builder = ResourceId.builder();
        } else {
            try {
                builder = parent.copyBuilder();
            } catch (CloneNotSupportedException e) {
                throw new IllegalArgumentException(e);
            }
        }

        SchemaId sid = node.key().schemaId();
        switch (node.type()) {
        case MULTI_INSTANCE_LEAF_VALUE_NODE:
            builder.addLeafListBranchPoint(sid.name(), sid.namespace(),
                                           ((LeafListKey) node.key()).asString());
            break;

        case MULTI_INSTANCE_NODE:
            builder.addBranchPointSchema(sid.name(), sid.namespace());
            for (KeyLeaf keyLeaf : ((ListKey) node.key()).keyLeafs()) {
                builder.addKeyLeaf(keyLeaf.leafSchema().name(),
                                   keyLeaf.leafSchema().namespace(),
                                   keyLeaf.leafValAsString());
            }
            break;

        case SINGLE_INSTANCE_LEAF_VALUE_NODE:
        case SINGLE_INSTANCE_NODE:
            builder.addBranchPointSchema(sid.name(), sid.namespace());
            break;

        default:
            throw new IllegalArgumentException("Unknown type " + node);

        }

        return builder.build();
    }

    /**
     * Concats {@code path} after {@code prefix}.
     *
     * @param prefix path
     * @param path to append after {@code path}
     * @return concatenated ResouceId
     */
    public static ResourceId concat(ResourceId prefix, ResourceId path) {
        checkArgument(!path.nodeKeys().contains(DeviceResourceIds.ROOT_NODE),
                      "%s was already absolute path", path);
        try {
            return prefix.copyBuilder().append(path).build();
        } catch (CloneNotSupportedException e) {
            log.error("Could not copy {}", path, e);
            throw new IllegalArgumentException("Could not copy " + path, e);
        }
    }


    /**
     * Returns {@code child} ad relative ResourceId against {@code base}.
     *
     * @param base ResourceId
     * @param child ResourceId to relativize
     * @return relative ResourceId
     */
    public static ResourceId relativize(ResourceId base, ResourceId child) {
        checkArgument(child.nodeKeys().size() >= base.nodeKeys().size(),
                      "%s path must be deeper than base prefix %s", child, base);
        checkArgument(base.nodeKeys().equals(child.nodeKeys().subList(0, base.nodeKeys().size())),
                      "%s is not a prefix of %s", child, base);

        // FIXME waiting for Yang tools 2.2.0-b4 or later
//        return ResourceId.builder().append(child.nodeKeys().subList(base.nodeKeys().size(),
//                                                                    child.nodeKeys().size())).build();

        Builder builder = ResourceId.builder();
        for (NodeKey nodeKey : child.nodeKeys().subList(base.nodeKeys().size(),
                                                        child.nodeKeys().size())) {
            if (nodeKey instanceof ListKey) {
                ListKey listKey = (ListKey) nodeKey;
                for (KeyLeaf keyLeaf : listKey.keyLeafs()) {
                    builder.addKeyLeaf(keyLeaf.leafSchema().name(),
                                       keyLeaf.leafSchema().namespace(),
                                       keyLeaf.leafValAsString());
                }
            } else if (nodeKey instanceof LeafListKey) {
                LeafListKey llKey = (LeafListKey) nodeKey;
                builder.addLeafListBranchPoint(llKey.schemaId().name(),
                                               llKey.schemaId().namespace(),
                                               llKey.value());

            } else {
                builder.addBranchPointSchema(nodeKey.schemaId().name(),
                                             nodeKey.schemaId().namespace());
            }
        }
        return builder.build();
    }

    /**
     * Tests if {@code child} starts with {@code prefix}.
     *
     * @param prefix expected
     * @param child to test
     * @return true if {@code child} starts with {@code prefix}
     */
    public static boolean isPrefix(ResourceId prefix, ResourceId child) {

        return child.nodeKeys().size() >= prefix.nodeKeys().size() &&
               prefix.nodeKeys().equals(child.nodeKeys().subList(0, prefix.nodeKeys().size()));
    }

}
