/*
 * Copyright 2016-present 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.linker.impl;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.onosproject.yangutils.datamodel.ResolvableType;
import org.onosproject.yangutils.datamodel.YangImport;
import org.onosproject.yangutils.datamodel.YangInclude;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangReferenceResolver;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.linker.YangLinker;
import org.onosproject.yangutils.linker.exceptions.LinkerException;

import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;

/**
 * Representation of entity which provides linking service of YANG files.
 */
public class YangLinkerManager
        implements YangLinker {

    /*
     * Set of all the YANG nodes, corresponding to the YANG files parsed by
     * parser.
     */
    Set<YangNode> yangNodeSet = new HashSet<>();

    /**
     * Returns set of YANG node.
     *
     * @return set of YANG node
     */
    public Set<YangNode> getYangNodeSet() {
        return yangNodeSet;
    }

    /**
     * Creates YANG nodes set.
     *
     * @param yangNodeSet YANG node information set
     */
    public void createYangNodeSet(Set<YangNode> yangNodeSet) {
        getYangNodeSet().addAll(yangNodeSet);
    }

    @Override
    public void resolveDependencies(Set<YangNode> yangNodeSet) {

        // Create YANG node set.
        createYangNodeSet(yangNodeSet);

        // Carry out linking of sub module with module.
        linkSubModulesToParentModule(yangNodeSet);

        // Add references to import list.
        addRefToYangFilesImportList(yangNodeSet);

        // Add reference to include list.
        addRefToYangFilesIncludeList(yangNodeSet);

        // Update the priority for all the files.
        updateFilePriority(yangNodeSet);

        // TODO check for circular import/include.

        // Carry out inter-file linking.
        processInterFileLinking(yangNodeSet);
    }

    /**
     * Resolves sub-module linking by linking sub module with parent module.
     *
     * @param yangNodeSet set of YANG files info
     * @throws LinkerException fails to link sub-module to parent module
     */
    public void linkSubModulesToParentModule(Set<YangNode> yangNodeSet)
            throws LinkerException {
        for (YangNode yangNode : yangNodeSet) {
            if (yangNode instanceof YangSubModule) {
                try {
                    ((YangSubModule) yangNode).linkWithModule(getYangNodeSet());
                } catch (DataModelException e) {
                    String errorInfo = "YANG file error: " + yangNode.getName() + " at line: "
                            + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE
                            + e.getMessage();
                    throw new LinkerException(errorInfo);
                    // TODO add file path in exception message in util manager.
                }
            }
        }
    }

    /**
     * Adds imported node information to the import list.
     *
     * @param yangNodeSet set of YANG files info
     * @throws LinkerException fails to find imported module
     */
    public void addRefToYangFilesImportList(Set<YangNode> yangNodeSet) throws LinkerException {
        for (YangNode yangNode : yangNodeSet) {
            if (yangNode instanceof YangReferenceResolver) {
                try {
                    ((YangReferenceResolver) yangNode).addReferencesToImportList(getYangNodeSet());
                } catch (DataModelException e) {
                    String errorInfo = "Error in file: " + yangNode.getName() + " at line: "
                            + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE
                            + e.getMessage();
                    throw new LinkerException(errorInfo);
                    // TODO add file path in exception message in util manager.
                }
            }
        }
    }

    /**
     * Adds included node information to the include list.
     *
     * @param yangNodeSet set of YANG files info
     * @throws LinkerException fails to find included sub-module
     */
    public void addRefToYangFilesIncludeList(Set<YangNode> yangNodeSet) throws LinkerException {
        for (YangNode yangNode : yangNodeSet) {
            if (yangNode instanceof YangReferenceResolver) {
                try {
                    ((YangReferenceResolver) yangNode).addReferencesToIncludeList(getYangNodeSet());
                } catch (DataModelException e) {
                    String errorInfo = "Error in file: " + yangNode.getName() + " at line: "
                            + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE
                            + e.getMessage();
                    throw new LinkerException(errorInfo);
                    // TODO add file path in exception message in util manager.
                }
            }
        }
    }

    /**
     * Processes inter file linking for type and uses.
     *
     * @param yangNodeSet set of YANG files info
     * @throws LinkerException a violation in linker execution
     */
    public void processInterFileLinking(Set<YangNode> yangNodeSet)
            throws LinkerException {
        List<YangNode> yangNodeSortedList = new LinkedList<>();
        yangNodeSortedList.addAll(yangNodeSet);
        Collections.sort(yangNodeSortedList);
        for (YangNode yangNode : yangNodeSortedList) {
            try {
                ((YangReferenceResolver) yangNode)
                        .resolveInterFileLinking(ResolvableType.YANG_IF_FEATURE);
                ((YangReferenceResolver) yangNode)
                        .resolveInterFileLinking(ResolvableType.YANG_USES);
                ((YangReferenceResolver) yangNode)
                .resolveInterFileLinking(ResolvableType.YANG_AUGMENT);
                ((YangReferenceResolver) yangNode)
                        .resolveInterFileLinking(ResolvableType.YANG_DERIVED_DATA_TYPE);
                ((YangReferenceResolver) yangNode)
                        .resolveInterFileLinking(ResolvableType.YANG_LEAFREF);
                ((YangReferenceResolver) yangNode)
                        .resolveInterFileLinking(ResolvableType.YANG_BASE);
                ((YangReferenceResolver) yangNode)
                        .resolveInterFileLinking(ResolvableType.YANG_IDENTITYREF);
            } catch (DataModelException e) {
                String errorInfo = "Error in file: " + yangNode.getName() + " at line: "
                        + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE + e.getMessage();
                throw new LinkerException(errorInfo);
                // TODO add file path in exception message in util manager.
            }
        }
    }

    /**
     * Updates the priority for all the input files.
     *
     * @param yangNodeSet set of YANG files info
     */
    public void updateFilePriority(Set<YangNode> yangNodeSet) {
        for (YangNode yangNode : yangNodeSet) {
            updateFilePriorityOfNode(yangNode);
        }
    }

    /**
     * Updates priority of the node.
     *
     * @param yangNode YANG node information
     */
    public void updateFilePriorityOfNode(YangNode yangNode) {
        int curNodePriority = yangNode.getPriority();
        if (yangNode instanceof YangReferenceResolver) {
            List<YangImport> yangImportList = ((YangReferenceResolver) yangNode).getImportList();
            if (yangImportList != null && !yangImportList.isEmpty()) {
                Iterator<YangImport> importInfoIterator = yangImportList.iterator();
                // Run through the imported list to update priority.
                while (importInfoIterator.hasNext()) {
                    YangImport yangImport = importInfoIterator.next();
                    YangNode importedNode = yangImport.getImportedNode();
                    if (curNodePriority >= importedNode.getPriority()) {
                        importedNode.setPriority(curNodePriority + 1);
                        updateFilePriorityOfNode(importedNode);
                    }
                }
            }

            List<YangInclude> yangIncludeList = ((YangReferenceResolver) yangNode).getIncludeList();
            if (yangIncludeList != null && !yangIncludeList.isEmpty()) {
                Iterator<YangInclude> includeInfoIterator = yangIncludeList.iterator();
                // Run through the imported list to update priority.
                while (includeInfoIterator.hasNext()) {
                    YangInclude yangInclude = includeInfoIterator.next();
                    YangNode includedNode = yangInclude.getIncludedNode();
                    if (curNodePriority >= includedNode.getPriority()) {
                        includedNode.setPriority(curNodePriority + 1);
                        updateFilePriorityOfNode(includedNode);
                    }
                }
            }
        }
    }
}
