/*
 * Copyright 2016 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.yangutils.translator.tojava;

import java.io.IOException;

import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.translator.exception.TranslatorException;

import static org.onosproject.yangutils.translator.tojava.TraversalType.CHILD;
import static org.onosproject.yangutils.translator.tojava.TraversalType.PARENT;
import static org.onosproject.yangutils.translator.tojava.TraversalType.ROOT;
import static org.onosproject.yangutils.translator.tojava.TraversalType.SIBILING;

/**
 * Implementation of Java code generator based on application schema.
 */
public final class JavaCodeGeneratorUtil {

    /**
     * Current YANG node.
     */
    private static YangNode curNode;

    /**
     * Default constructor.
     */
    private JavaCodeGeneratorUtil() {
    }

    /**
     * Returns current YANG node.
     *
     * @return current YANG node
     */
    public static YangNode getCurNode() {
        return curNode;
    }

    /**
     * Sets current YANG node.
     *
     * @param node current YANG node
     */

    public static void setCurNode(YangNode node) {
        curNode = node;
    }

    /**
     * Generate Java code files corresponding to the YANG schema.
     *
     * @param rootNode root node of the data model tree
     * @param codeGenDir code generation directory
     * @throws IOException when fails to generate java code file the current
     *             node
     */
    public static void generateJavaCode(YangNode rootNode, String codeGenDir) throws IOException {

        YangNode curNode = rootNode;
        TraversalType curTraversal = ROOT;

        while (!(curNode == null)) {
            if (curTraversal != PARENT) {
                setCurNode(curNode);
                generateCodeEntry(curNode, codeGenDir);
            }
            if (curTraversal != PARENT && curNode.getChild() != null) {
                curTraversal = CHILD;
                curNode = curNode.getChild();
            } else if (curNode.getNextSibling() != null) {
                generateCodeExit(curNode);
                curTraversal = SIBILING;
                curNode = curNode.getNextSibling();
            } else {
                generateCodeExit(curNode);
                curTraversal = PARENT;
                curNode = curNode.getParent();
            }
        }
    }

    /**
     * Generates the current nodes code snippet.
     *
     * @param curNode current data model node for which the code needs to be
     *            generated
     * @param codeGenDir the base directory where the code needs to be generated
     * @throws IOException IO operation exception
     */
    private static void generateCodeEntry(YangNode curNode,
            String codeGenDir) throws IOException {

        if (curNode instanceof JavaCodeGenerator) {
            ((JavaCodeGenerator) curNode).generateCodeEntry(codeGenDir);
        } else {
            throw new TranslatorException(
                    "Generated data model node cannot be translated to target language code");
        }
    }

    /**
     * Generates the current nodes code target code from the snippet.
     *
     * @param curNode current data model node for which the code needs to be
     *            generated
     * @throws IOException IO operation exception
     */
    private static void generateCodeExit(YangNode curNode) throws IOException {

        if (curNode instanceof JavaCodeGenerator) {
            ((JavaCodeGenerator) curNode).generateCodeExit();
        } else {
            throw new TranslatorException(
                    "Generated data model node cannot be translated to target language code");
        }
    }

    /**
     * Free other YANG nodes of data-model tree when error occurs while file generation of current node.
     *
     * @throws DataModelException when fails to do datamodel operations
     */
    public static void freeRestResources() throws DataModelException {

        YangNode curNode = getCurNode();
        YangNode tempNode = curNode;
        TraversalType curTraversal = ROOT;

        while (!(curNode == tempNode.getParent())) {

            if (curTraversal != PARENT && curNode.getChild() != null) {
                curTraversal = CHILD;
                curNode = curNode.getChild();
            } else if (curNode.getNextSibling() != null) {
                curTraversal = SIBILING;
                if (curNode != tempNode) {
                    free(curNode);
                }
                curNode = curNode.getNextSibling();
            } else {
                curTraversal = PARENT;
                if (curNode != tempNode) {
                    free(curNode);
                }
                curNode = curNode.getParent();
            }
        }
    }

    /**
     * Free the current node.
     *
     * @param node YANG node
     * @throws DataModelException when fails to do datamodel operations
     */
    private static void free(YangNode node) throws DataModelException {

        YangNode parent = node.getParent();
        parent.setChild(null);
        if (node.getNextSibling() != null) {
            parent.setChild(node.getNextSibling());
        } else if (node.getPreviousSibling() != null) {
            parent.setChild(node.getPreviousSibling());
        }
        node = null;
    }

    /**
     * Delete Java code files corresponding to the YANG schema.
     *
     * @param rootNode root node of data-model tree
     * @throws IOException when fails to delete java code file the current node
     * @throws DataModelException when fails to do datamodel operations
     */
    public static void translatorErrorHandler(YangNode rootNode) throws IOException, DataModelException {

        /**
         * Free other resources where translator has failed.
         */
        freeRestResources();

        /**
         * Start removing all open files.
         */
        YangNode curNode = rootNode;
        setCurNode(curNode.getChild());
        TraversalType curTraversal = ROOT;

        while (!(curNode == null)) {

            if (curTraversal != PARENT) {
                close(curNode);
            }
            if (curTraversal != PARENT && curNode.getChild() != null) {
                curTraversal = CHILD;
                curNode = curNode.getChild();
            } else if (curNode.getNextSibling() != null) {
                curTraversal = SIBILING;
                curNode = curNode.getNextSibling();
            } else {
                curTraversal = PARENT;
                curNode = curNode.getParent();
            }
        }

        freeRestResources();
        curNode = null;
    }

    /**
     * Closes all the current open file handles of node and delete all generated files.
     *
     * @param curNode current YANG node
     * @throws IOException when fails to do IO operations
     */
    private static void close(YangNode curNode) throws IOException {

        if (((HasTempJavaCodeFragmentFiles) curNode).getTempJavaCodeFragmentFiles() != null) {
            ((HasTempJavaCodeFragmentFiles) curNode).getTempJavaCodeFragmentFiles().close(true);
        }
    }
}
