/*
 * Copyright 2018-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.workflow.api;


import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.MissingNode;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.google.common.base.MoreObjects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

/**
 * Class for json data model tree.
 */
public final class JsonDataModelTree implements DataModelTree {

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

    /**
     * Root node of json data model tree.
     */
    private JsonNode root;

    /**
     * Constructor of JsonDataModelTree.
     */
    public JsonDataModelTree() {
        this.root = JsonNodeFactory.instance.objectNode();
    }

    /**
     * Constructor of JsonDataModelTree.
     * @param root root node of json data model tree
     */
    public JsonDataModelTree(JsonNode root) {
        this.root = root;
    }

    @Override
    public DataModelTree subtree(String path) {
        JsonNode node = root.at(path);
        if (Objects.isNull(node) || node.isMissingNode()) {
            return null;
        }
        return new JsonDataModelTree(node);
    }

    @Override
    public void attach(String path, DataModelTree tree) throws WorkflowException {

        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }

        JsonPointer ptr = JsonPointer.compile(path);

        if (!(tree instanceof JsonDataModelTree)) {
            throw new WorkflowException("Invalid subTree(" + tree + ")");
        }
        JsonNode attachingNode = ((JsonDataModelTree) tree).root();

        attach(ptr, attachingNode);
    }

    private void attach(JsonPointer ptr, JsonNode attachingNode) throws WorkflowException {

        JsonNode node = root.at(ptr);
        if (!(node instanceof MissingNode)) {
            throw new WorkflowException("Path(" + ptr + ") has already subtree(" + node + ")");
        }

        if (ptr.last().getMatchingIndex() != -1) {

            alloc(ptr.head(), Nodetype.ARRAY);
            JsonNode parentNode = root.at(ptr.head());
            if (!parentNode.isArray()) {
                throw new WorkflowException("Invalid parentNode type(" + parentNode.getNodeType() + " != Array)");
            }
            int index = ptr.last().getMatchingIndex();
            ((ArrayNode) parentNode).insert(index, attachingNode);

        } else if (ptr.last().getMatchingProperty() != null) {

            alloc(ptr.head(), Nodetype.MAP);
            JsonNode parentNode = root.at(ptr.head());
            if (!parentNode.isObject()) {
                throw new WorkflowException("Invalid parentNode type(" + parentNode.getNodeType() + " != Object)");
            }
            String key = ptr.last().getMatchingProperty();
            ((ObjectNode) parentNode).put(key, attachingNode);

        } else {
            throw new WorkflowException("Invalid path(" + ptr + ")");
        }
    }

    @Override
    public void remove(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        remove(ptr);
    }

    private void remove(JsonPointer ptr) throws WorkflowException {

        JsonNode node = root.at(ptr);
        if (node instanceof MissingNode) {
            log.warn("{} does not have valid node", ptr);
            return;
        }

        if (ptr.last().getMatchingIndex() != -1) {

            JsonNode parentNode = root.at(ptr.head());
            if (!parentNode.isArray()) {
                throw new WorkflowException("Invalid parentNode type(" + parentNode.getNodeType() + " != Array)");
            }
            int index = ptr.last().getMatchingIndex();
            ((ArrayNode) parentNode).remove(index);

        } else if (ptr.last().getMatchingProperty() != null) {

            JsonNode parentNode = root.at(ptr.head());
            if (!parentNode.isObject()) {
                throw new WorkflowException("Invalid parentNode type(" + parentNode.getNodeType() + " != Object)");
            }
            String key = ptr.last().getMatchingProperty();
            ((ObjectNode) parentNode).remove(key);

        } else {
            throw new WorkflowException("Invalid path(" + ptr + ")");
        }
    }

    @Override
    public JsonDataModelTree alloc(String path, Nodetype leaftype) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }

        JsonPointer ptr = JsonPointer.compile(path);
        return alloc(ptr, leaftype);
    }

    /**
     * Allocates json data model tree on json pointer path with specific leaf type.
     * @param ptr json pointer to allocate
     * @param leaftype type of leaf node
     * @return json data model tree
     * @throws WorkflowException workflow exception
     */
    private JsonDataModelTree alloc(JsonPointer ptr, Nodetype leaftype) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }

        switch (leaftype) {
            case MAP:
                alloc(root, ptr, JsonNodeType.OBJECT);
                break;
            case ARRAY:
                alloc(root, ptr, JsonNodeType.ARRAY);
                break;
            default:
                throw new WorkflowException("Not supported leaftype(" + leaftype + ")");
        }
        return this;
    }

    /**
     * Gets root json node.
     * @return root json node
     * @throws WorkflowException workflow exception
     */
    public JsonNode root() throws WorkflowException {
        return nodeAt("");
    }

    /**
     * Gets root json node as ObjectNode (MAP type).
     * @return root json node as ObjectNode
     * @throws WorkflowException workflow exception
     */
    public ObjectNode rootObject() throws WorkflowException {
        return objectAt("");
    }

    /**
     * Gets root json node as ArrayNode (Array type).
     * @return root json node as ArrayNode
     * @throws WorkflowException workflow exception
     */
    public ArrayNode rootArray() throws WorkflowException {
        return arrayAt("");
    }

    /**
     * Gets json node on specific path.
     * @param path path of json node
     * @return json node on specific path
     * @throws WorkflowException workflow exception
     */
    public JsonNode nodeAt(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        return nodeAt(ptr);
    }

    /**
     * Gets json node on specific json pointer.
     * @param ptr json pointer
     * @return json node on specific json pointer.
     * @throws WorkflowException workflow exception
     */
    public JsonNode nodeAt(JsonPointer ptr) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }
        JsonNode node = root.at(ptr);
        return node;
    }

    /**
     * Gets json node on specific path as ObjectNode.
     * @param path path of json node
     * @return ObjectNode type json node on specific path
     * @throws WorkflowException workflow exception
     */
    public ObjectNode objectAt(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        return objectAt(ptr);
    }

    /**
     * Gets json node on specific json pointer as ObjectNode.
     * @param ptr json pointer
     * @return ObjectNode type json node on specific json pointer.
     * @throws WorkflowException workflow exception
     */
    public ObjectNode objectAt(JsonPointer ptr) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }
        JsonNode node = root.at(ptr);
        if (node instanceof MissingNode) {
            return null;
        }
        if (!(node instanceof ObjectNode)) {
            throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
        }
        return (ObjectNode) node;
    }

    /**
     * Gets json node on specific path as ArrayNode.
     * @param path path of json node
     * @return ArrayNode type json node on specific path
     * @throws WorkflowException workflow exception
     */
    public ArrayNode arrayAt(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        return arrayAt(ptr);
    }

    /**
     * Gets json node on specific json pointer as ArrayNode.
     * @param ptr json pointer
     * @return ArrayNode type json node on specific json pointer.
     * @throws WorkflowException workflow exception
     */
    public ArrayNode arrayAt(JsonPointer ptr) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }
        JsonNode node = root.at(ptr);
        if (node instanceof MissingNode) {
            return null;
        }
        if (!(node instanceof ArrayNode)) {
            throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
        }
        return (ArrayNode) node;
    }

    /**
     * Gets text node on specific path.
     * @param path path of json node
     * @return text on specific path
     * @throws WorkflowException workflow exception
     */
    public String textAt(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        return textAt(ptr);
    }

    /**
     * Gets text on specific json pointer.
     * @param ptr json pointer
     * @return text on specific json pointer
     * @throws WorkflowException workflow exception
     */
    public String textAt(JsonPointer ptr) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }
        JsonNode node = root.at(ptr);
        if (node instanceof MissingNode) {
            return null;
        }
        if (!(node instanceof TextNode)) {
            throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
        }
        return ((TextNode) node).asText();
    }

    /**
     * Gets integer node on specific path.
     * @param path path of json node
     * @return integer on specific path
     * @throws WorkflowException workflow exception
     */
    public Integer intAt(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        return intAt(ptr);
    }

    /**
     * Gets integer on specific json pointer.
     * @param ptr json pointer
     * @return integer on specific json pointer
     * @throws WorkflowException workflow exception
     */
    public Integer intAt(JsonPointer ptr) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }
        JsonNode node = root.at(ptr);
        if (node instanceof MissingNode) {
            return null;
        }
        if (!(node instanceof NumericNode)) {
            throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
        }
        return ((NumericNode) node).asInt();
    }

    /**
     * Gets boolean on specific path.
     * @param path path of json node
     * @return boolean on specific path
     * @throws WorkflowException workflow exception
     */
    public Boolean booleanAt(String path) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        return booleanAt(ptr);
    }

    /**
     * Gets boolean on specific json pointer.
     * @param ptr json pointer
     * @return boolean on specific json pointer
     * @throws WorkflowException workflow exception
     */
    public Boolean booleanAt(JsonPointer ptr) throws WorkflowException {
        if (root == null || root instanceof MissingNode) {
            throw new WorkflowException("Invalid root node");
        }
        JsonNode node = root.at(ptr);
        if (node instanceof MissingNode) {
            return null;
        }
        if (!(node instanceof BooleanNode)) {
            throw new WorkflowException("Invalid node(" + node + ") at " + ptr);
        }
        return ((BooleanNode) node).asBoolean();
    }

    /**
     * Sets text on specific json path.
     * @param path json path
     * @param text text to set
     * @throws WorkflowException workflow exception
     */
    public void setAt(String path, String text) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        setAt(ptr, text);
    }

    /**
     * Sets text on the specific json pointer.
     * @param ptr json pointer
     * @param text text to set
     * @throws WorkflowException workflow exception
     */
    public void setAt(JsonPointer ptr, String text) throws WorkflowException {
        TextNode textNode = TextNode.valueOf(text);
        attach(ptr, textNode);
    }

    /**
     * Sets boolean on specific json path.
     * @param path json path
     * @param isTrue boolean to set
     * @throws WorkflowException workflow exception
     */
    public void setAt(String path, Boolean isTrue) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        setAt(ptr, isTrue);
    }

    /**
     * Sets boolean on the specific json pointer.
     * @param ptr json pointer
     * @param isTrue boolean to set
     * @throws WorkflowException workflow exception
     */
    public void setAt(JsonPointer ptr, Boolean isTrue) throws WorkflowException {
        BooleanNode booleanNode = BooleanNode.valueOf(isTrue);
        attach(ptr, booleanNode);
    }

    /**
     * Sets integer on specific json path.
     * @param path json path
     * @param number number to set
     * @throws WorkflowException workflow exception
     */
    public void setAt(String path, Integer number) throws WorkflowException {
        JsonPointer ptr = JsonPointer.compile(path);
        setAt(ptr, number);
    }

    /**
     * Sets integer on the specific json pointer.
     * @param ptr json pointer
     * @param number number to set
     * @throws WorkflowException workflow exception
     */
    public void setAt(JsonPointer ptr, Integer number) throws WorkflowException {
        IntNode intNode = IntNode.valueOf(number);
        attach(ptr, intNode);
    }

    /**
     * Allocates json data model tree on json pointer path with specific leaf type.
     * @param node current json node in the json tree path
     * @param ptr json pointer
     * @param leaftype leaf type to be allocated
     * @return allocated json node
     * @throws WorkflowException workflow exception
     */
    private JsonNode alloc(JsonNode node, JsonPointer ptr, JsonNodeType leaftype) throws WorkflowException {

        if (ptr.matches()) {
            if (node == null || node instanceof MissingNode) {
                node = createEmpty(leaftype);
            } else {
                //TODO: checking existing node type is matched with leaftype
                if (!Objects.equals(node.getNodeType(), leaftype)) {
                    throw new WorkflowException("Requesting leaftype(" + leaftype + ") is not matched with "
                            + "existing nodetype(" + node.getNodeType() + ") for " + ptr);
                }
            }
            return node;
        }

        if (ptr.getMatchingIndex() != -1) {
            if (node == null || node instanceof MissingNode) {
                node = createEmpty(JsonNodeType.ARRAY);
            }
            JsonNode child = alloc(node.get(ptr.getMatchingIndex()), ptr.tail(), leaftype);
            if (!node.has(ptr.getMatchingIndex())) {
                ((ArrayNode) node).insert(ptr.getMatchingIndex(), child);
            }
        } else if (ptr.getMatchingProperty() != null) {
            if (node == null || node instanceof MissingNode) {
                node = createEmpty(JsonNodeType.OBJECT);
            }
            JsonNode child = alloc(node.get(ptr.getMatchingProperty()), ptr.tail(), leaftype);
            if (!node.has(ptr.getMatchingProperty())) {
                ((ObjectNode) node).put(ptr.getMatchingProperty(), child);
            }
        }
        return node;
    }

    /**
     * Creating empty json node.
     * @param type json node type to create
     * @return created json node
     * @throws WorkflowException workflow exception
     */
    private JsonNode createEmpty(JsonNodeType type) throws WorkflowException {
        if (type == JsonNodeType.OBJECT) {
            return JsonNodeFactory.instance.objectNode();
        } else if (type == JsonNodeType.ARRAY) {
            return JsonNodeFactory.instance.arrayNode();
        } else if (type == JsonNodeType.STRING) {
            return JsonNodeFactory.instance.textNode("");
        } else {
            throw new WorkflowException("Not supported JsonNodetype(" + type + ")");
        }
    }

    /**
     * Gets the pretty json formatted string of this json data model tree.
     * @return pretty json formatted string of this json data model tree
     */
    public String formattedRootString() {
        String str = "";
        try {
            str = (new ObjectMapper()).writerWithDefaultPrettyPrinter().writeValueAsString(root);
        } catch (JsonProcessingException e) {
            log.error("Exception: ", e);
        }
        return str;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("json", root)
                .toString();
    }
}

