/*
 * Copyright 2016-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.store.primitives.resources.impl;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

import org.onosproject.store.service.DocumentPath;
import org.onosproject.store.service.DocumentTreeNode;
import org.onosproject.store.service.Ordering;
import org.onosproject.store.service.Versioned;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * A {@code DocumentTree} node.
 */
public class DefaultDocumentTreeNode<V> implements DocumentTreeNode<V> {
    private final DocumentPath key;
    private Versioned<V> value;
    private final Map<String, DocumentTreeNode<V>> children;
    private final Ordering ordering;
    private final DocumentTreeNode<V> parent;

    public DefaultDocumentTreeNode(DocumentPath key,
            V value,
            long version,
            Ordering ordering,
            DocumentTreeNode<V> parent) {
        this.key = checkNotNull(key);
        this.value = new Versioned<>(value, version);
        this.ordering = ordering;
        this.parent = parent;

        switch (ordering) {
            case INSERTION:
                children = Maps.newLinkedHashMap();
                break;
            case NATURAL:
            default:
                children = Maps.newTreeMap();
                break;
        }
    }

    @Override
    public DocumentPath path() {
        return key;
    }

    @Override
    public Versioned<V> value() {
        return value;
    }

    @Override
    public Iterator<DocumentTreeNode<V>> children() {
        return ImmutableList.copyOf(children.values()).iterator();
    }

    @Override
    public DocumentTreeNode<V> child(String name) {
        return children.get(name);
    }


    public DocumentTreeNode<V> parent() {
        return parent;
    }

    /**
     * Adds a new child only if one does not exist with the name.
     * @param name relative path name of the child node
     * @param newValue new value to set
     * @param newVersion new version to set
     * @return previous value; can be {@code null} if no child currently exists with that relative path name.
     * a non null return value indicates child already exists and no modification occurred.
     */
    public Versioned<V> addChild(String name, V newValue, long newVersion) {
        DefaultDocumentTreeNode<V> child = (DefaultDocumentTreeNode<V>) children.get(name);
        if (child != null) {
            return child.value();
        }
        children.put(name, new DefaultDocumentTreeNode<>(
                new DocumentPath(name, path()), newValue, newVersion, ordering, this));
        return null;
    }

    /**
     * Updates the node value.
     *
     * @param newValue new value to set
     * @param newVersion new version to set
     * @return previous value
     */
    public Versioned<V> update(V newValue, long newVersion) {
        Versioned<V> previousValue = value;
        value = new Versioned<>(newValue, newVersion);
        return previousValue;
    }


    /**
     * Removes a child node.
     *
     * @param name the name of child node to be removed
     * @return {@code true} if the child set was modified as a result of this call, {@code false} otherwise
     */
    public boolean removeChild(String name) {
        return children.remove(name) != null;
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.key);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof DefaultDocumentTreeNode) {
            DefaultDocumentTreeNode<V> that = (DefaultDocumentTreeNode<V>) obj;
            if (this.parent.equals(that.parent)) {
                if (this.children.size() == that.children.size()) {
                    return Sets.symmetricDifference(this.children.keySet(), that.children.keySet()).isEmpty();
                }
            }
        }
        return false;
    }

    @Override
    public String toString() {
        MoreObjects.ToStringHelper helper =
                MoreObjects.toStringHelper(getClass())
                        .add("parent", this.parent)
                        .add("key", this.key)
                        .add("value", this.value);
        for (DocumentTreeNode<V> child : children.values()) {
            helper = helper.add("child", "\n" + child.path().pathElements()
                    .get(child.path().pathElements().size() - 1) +
                    " : " + child.value());
        }
        return helper.toString();
    }
}