/*
 * 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.datamodel;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;

import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.linkInterFileReferences;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLinkingForResolutionList;

/*-
 * Reference:RFC 6020.
 * The "module" statement defines the module's name,
 * and groups all statements that belong to the module together. The "module"
 * statement's argument is the name of the module, followed by a block of
 * sub statements that hold detailed module information.
 * The module's sub statements
 *
 *                +--------------+---------+-------------+-----------------------+
 *                |sub statement | section | cardinality | data model mapping    |
 *                +--------------+---------+-------------+-----------------------+
 *                | anyxml       | 7.10    | 0..n        | not supported         |
 *                | augment      | 7.15    | 0..n        | child nodes           |
 *                | choice       | 7.9     | 0..n        | child nodes           |
 *                | contact      | 7.1.8   | 0..1        | string                |
 *                | container    | 7.5     | 0..n        | child nodes           |
 *                | description  | 7.19.3  | 0..1        | string                |
 *                | deviation    | 7.18.3  | 0..n        | TODO                  |
 *                | extension    | 7.17    | 0..n        | TODO                  |
 *                | feature      | 7.18.1  | 0..n        | TODO                  |
 *                | grouping     | 7.11    | 0..n        | child nodes           |
 *                | identity     | 7.16    | 0..n        | TODO                  |
 *                | import       | 7.1.5   | 0..n        | list of import info   |
 *                | include      | 7.1.6   | 0..n        | list of include info  |
 *                | leaf         | 7.6     | 0..n        | list of leaf info     |
 *                | leaf-list    | 7.7     | 0..n        | list of leaf-list info|
 *                | list         | 7.8     | 0..n        | child nodes           |
 *                | namespace    | 7.1.3   | 1           | string/uri            |
 *                | notification | 7.14    | 0..n        | TODO                  |
 *                | organization | 7.1.7   | 0..1        | string                |
 *                | prefix       | 7.1.4   | 1           | string                |
 *                | reference    | 7.19.4  | 0..1        | string                |
 *                | revision     | 7.1.9   | 0..n        | revision              |
 *                | rpc          | 7.13    | 0..n        | TODO                  |
 *                | typedef      | 7.3     | 0..n        | child nodes           |
 *                | uses         | 7.12    | 0..n        | child nodes           |
 *                | YANG-version | 7.1.2   | 0..1        | int                   |
 *                +--------------+---------+-------------+-----------------------+
 */

/**
 * Represents data model node to maintain information defined in YANG module.
 */
public class YangModule
        extends YangNode
        implements YangLeavesHolder, YangDesc, YangReference, Parsable, CollisionDetector, YangReferenceResolver,
        RpcNotificationContainer, YangFeatureHolder {

    private static final long serialVersionUID = 806201610L;

    /**
     * Name of the module.
     */
    private String name;

    /**
     * Reference:RFC 6020.
     *
     * The "contact" statement provides contact information for the module. The
     * argument is a string that is used to specify contact information for the
     * person or persons to whom technical queries concerning this module should
     * be sent, such as their name, postal address, telephone number, and
     * electronic mail address.
     */
    private String contact;

    /**
     * Reference:RFC 6020.
     *
     * The "description" statement takes as an argument a string that contains a
     * human-readable textual description of this definition. The text is
     * provided in a language (or languages) chosen by the module developer; for
     * the sake of interoperability.
     */
    private String description;

    /**
     * List of YANG modules imported.
     */
    private List<YangImport> importList;

    /**
     * List of YANG sub-modules included.
     */
    private List<YangInclude> includeList;

    /**
     * List of leaves at root level in the module.
     */
    private List<YangLeaf> listOfLeaf;

    /**
     * List of leaf-lists at root level in the module.
     */
    private List<YangLeafList> listOfLeafList;

    /**
     * List of feature at root level in the module.
     */
    private List<YangFeature> listOfFeature;

    /**
     * Name space of the module.
     */
    private YangNameSpace nameSpace;

    /**
     * Reference:RFC 6020.
     *
     * The "organization" statement defines the party responsible for this
     * module. The argument is a string that is used to specify a textual
     * description of the organization(s) under whose auspices this module was
     * developed.
     */
    private String organization;

    /**
     * Prefix to refer to the objects in module.
     */
    private String prefix;

    /**
     * Reference of the module.
     */
    private String reference;

    /**
     * Revision info of the module.
     */
    private YangRevision revision;

    /**
     * YANG version.
     */
    private byte version;

    /*-
     * Reference RFC 6020.
     *
     * Nested typedefs and groupings.
     * Typedefs and groupings may appear nested under many YANG statements,
     * allowing these to be lexically scoped by the hierarchy under which
     * they appear.  This allows types and groupings to be defined near
     * where they are used, rather than placing them at the top level of the
     * hierarchy.  The close proximity increases readability.
     *
     * Scoping also allows types to be defined without concern for naming
     * conflicts between types in different submodules.  Type names can be
     * specified without adding leading strings designed to prevent name
     * collisions within large modules.
     *
     * Finally, scoping allows the module author to keep types and groupings
     * private to their module or submodule, preventing their reuse.  Since
     * only top-level types and groupings (i.e., those appearing as
     * sub-statements to a module or submodule statement) can be used outside
     * the module or submodule, the developer has more control over what
     * pieces of their module are presented to the outside world, supporting
     * the need to hide internal information and maintaining a boundary
     * between what is shared with the outside world and what is kept
     * private.
     *
     * Scoped definitions MUST NOT shadow definitions at a higher scope.  A
     * type or grouping cannot be defined if a higher level in the schema
     * hierarchy has a definition with a matching identifier.
     *
     * A reference to an unprefixed type or grouping, or one which uses the
     * prefix of the current module, is resolved by locating the closest
     * matching "typedef" or "grouping" statement among the immediate
     * sub-statements of each ancestor statement.
     */
    private List<YangResolutionInfo> derivedTypeResolutionList;

    /**
     * Uses resolution list.
     */
    private List<YangResolutionInfo> usesResolutionList;

    /**
     * If-feature resolution list.
     */
    private List<YangResolutionInfo> ifFeatureResolutionList;

    /**
     * Leafref resolution list.
     */
    private List<YangResolutionInfo> leafrefResolutionList;

    /**
     * Base resolution list.
     */
    private List<YangResolutionInfo> baseResolutionList;

    /**
     * Identityref resolution list.
     */
    private List<YangResolutionInfo> identityrefResolutionList;

    /**
     * Augment resolution list.
     */
    private List<YangResolutionInfo> augmentResolutionList;

    /**
     * Compiler annotation list.
     */
    private List<YangCompilerAnnotation> compilerAnnotationList;

    /**
     * Extension list.
     */
    private List<YangExtension> extensionList;

    /**
     * Creates a YANG node of module type.
     */
    public YangModule() {

        super(YangNodeType.MODULE_NODE);
        derivedTypeResolutionList = new LinkedList<>();
        augmentResolutionList = new LinkedList<>();
        usesResolutionList = new LinkedList<>();
        ifFeatureResolutionList = new LinkedList<>();
        leafrefResolutionList = new LinkedList<>();
        baseResolutionList = new LinkedList<>();
        identityrefResolutionList = new LinkedList<>();
        compilerAnnotationList = new LinkedList<>();
        importList = new LinkedList<YangImport>();
        includeList = new LinkedList<YangInclude>();
        listOfLeaf = new LinkedList<YangLeaf>();
        listOfLeafList = new LinkedList<YangLeafList>();
        extensionList = new LinkedList<YangExtension>();
    }

    /**
     * Returns name of the module.
     *
     * @return module name
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * Sets module name.
     *
     * @param moduleName module name
     */
    @Override
    public void setName(String moduleName) {
        name = moduleName;
    }

    /**
     * Returns the contact details of the module owner.
     *
     * @return the contact details of YANG owner
     */
    public String getContact() {
        return contact;
    }

    /**
     * Sets the contact details of the module owner.
     *
     * @param contact the contact details of YANG owner
     */
    public void setContact(String contact) {
        this.contact = contact;
    }

    /**
     * Returns the description of module.
     *
     * @return the description of YANG module
     */
    @Override
    public String getDescription() {
        return description;
    }

    /**
     * Sets the description of module.
     *
     * @param description set the description of YANG module
     */
    @Override
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Returns the list of imported modules.
     *
     * @return the list of imported modules
     */
    @Override
    public List<YangImport> getImportList() {
        return importList;
    }

    /**
     * Adds the imported module information to the import list.
     *
     * @param importedModule module being imported
     */
    @Override
    public void addToImportList(YangImport importedModule) {
        getImportList().add(importedModule);
    }

    @Override
    public void setImportList(List<YangImport> importList) {
        this.importList = importList;
    }

    /**
     * Returns the list of included sub modules.
     *
     * @return the included list of sub modules
     */
    @Override
    public List<YangInclude> getIncludeList() {
        return includeList;
    }

    /**
     * Adds the included sub module information to the include list.
     *
     * @param includeModule submodule being included
     */
    @Override
    public void addToIncludeList(YangInclude includeModule) {
        getIncludeList().add(includeModule);
    }

    @Override
    public void setIncludeList(List<YangInclude> includeList) {
        this.includeList = includeList;
    }

    /**
     * Returns the list of leaves in module.
     *
     * @return the list of leaves
     */
    @Override
    public List<YangLeaf> getListOfLeaf() {
        return listOfLeaf;
    }

    @Override
    public void setListOfLeaf(List<YangLeaf> leafsList) {
        listOfLeaf = leafsList;
    }

    /**
     * Adds a leaf in module.
     *
     * @param leaf the leaf to be added
     */
    @Override
    public void addLeaf(YangLeaf leaf) {
        getListOfLeaf().add(leaf);
    }

    /**
     * Returns the list of leaf-list from module.
     *
     * @return the list of leaf-list
     */
    @Override
    public List<YangLeafList> getListOfLeafList() {
        return listOfLeafList;
    }

    @Override
    public void setListOfLeafList(List<YangLeafList> listOfLeafList) {
        this.listOfLeafList = listOfLeafList;
    }


    /**
     * Adds a leaf-list in module.
     *
     * @param leafList the leaf-list to be added
     */
    @Override
    public void addLeafList(YangLeafList leafList) {
        getListOfLeafList().add(leafList);
    }

    @Override
    public List<YangFeature> getFeatureList() {
        return listOfFeature;
    }

    @Override
    public void addFeatureList(YangFeature feature) {
        if (getFeatureList() == null) {
            setListOfFeature(new LinkedList<>());
        }
        getFeatureList().add(feature);
    }

    @Override
    public void setListOfFeature(List<YangFeature> listOfFeature) {
        this.listOfFeature = listOfFeature;
    }

    /**
     * Returns the name space of module elements.
     *
     * @return the nameSpace
     */
    public YangNameSpace getNameSpace() {
        return nameSpace;
    }

    /**
     * Sets the name space of module elements.
     *
     * @param nameSpace the nameSpace to set
     */
    public void setNameSpace(YangNameSpace nameSpace) {
        this.nameSpace = nameSpace;
    }

    /**
     * Returns the modules organization.
     *
     * @return the organization
     */
    public String getOrganization() {
        return organization;
    }

    /**
     * Sets the modules organization.
     *
     * @param org the organization to set
     */
    public void setOrganization(String org) {
        organization = org;
    }

    /**
     * Returns the prefix.
     *
     * @return the prefix
     */
    @Override
    public String getPrefix() {
        return prefix;
    }

    /**
     * Sets the prefix.
     *
     * @param prefix the prefix to set
     */
    @Override
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    @Override
    public void resolveSelfFileLinking(ResolvableType type)
            throws DataModelException {
        // Get the list to be resolved.
        List<YangResolutionInfo> resolutionList = getUnresolvedResolutionList(type);
        // Resolve linking for a resolution list.
        resolveLinkingForResolutionList(resolutionList, this);
    }

    @Override
    public void resolveInterFileLinking(ResolvableType type)
            throws DataModelException {
        // Get the list to be resolved.
        List<YangResolutionInfo> resolutionList = getUnresolvedResolutionList(type);
        // Resolve linking for a resolution list.
        linkInterFileReferences(resolutionList, this);
    }

    /**
     * Returns the textual reference.
     *
     * @return the reference
     */
    @Override
    public String getReference() {
        return reference;
    }

    /**
     * Sets the textual reference.
     *
     * @param reference the reference to set
     */
    @Override
    public void setReference(String reference) {
        this.reference = reference;
    }

    /**
     * Returns the revision.
     *
     * @return the revision
     */
    public YangRevision getRevision() {
        return revision;
    }

    /**
     * Sets the revision.
     *
     * @param revision the revision to set
     */
    public void setRevision(YangRevision revision) {
        this.revision = revision;
    }

    /**
     * Returns the version.
     *
     * @return the version
     */
    public byte getVersion() {
        return version;
    }

    /**
     * Sets the version.
     *
     * @param version the version to set
     */
    public void setVersion(byte version) {
        this.version = version;
    }

    /**
     * Adds compiler annotation in compiler-annotation list.
     *
     * @param compilerAnnotation the compiler-annotation to be added
     */
    public void addCompilerAnnotation(YangCompilerAnnotation compilerAnnotation) {
        getCompilerAnnotationList().add(compilerAnnotation);
    }

    /**
     * Returns the compiler annotation list.
     *
     * @return the compiler annotation list
     */
    public List<YangCompilerAnnotation> getCompilerAnnotationList() {
        return compilerAnnotationList;
    }

    /**
     * Sets the compiler-annotation list.
     *
     * @param compilerAnnotationList the list of compiler-annotation
     */
    public void setCompilerAnnotationList(List<YangCompilerAnnotation> compilerAnnotationList) {
        this.compilerAnnotationList = compilerAnnotationList;
    }

    /**
     * Adds extension in extension list.
     *
     * @param extension the extension to be added
     */
    public void addExtension(YangExtension extension) {
        getExtensionList().add(extension);
    }

    /**
     * Returns the extension list.
     *
     * @return the extension list
     */
    public List<YangExtension> getExtensionList() {
        return extensionList;
    }

    /**
     * Sets the extension list.
     *
     * @param extensionList the list of extension
     */
    public void setExtensionList(List<YangExtension> extensionList) {
        this.extensionList = extensionList;
    }

    /**
     * Returns the type of the parsed data.
     *
     * @return returns MODULE_DATA
     */
    @Override
    public YangConstructType getYangConstructType() {
        return YangConstructType.MODULE_DATA;
    }

    /**
     * Validates the data on entering the corresponding parse tree node.
     *
     * @throws DataModelException a violation of data model rules
     */
    @Override
    public void validateDataOnEntry()
            throws DataModelException {
        /*
         * Module is root in the data model tree, hence there is no entry
         * validation
         */
    }

    /**
     * Validates the data on exiting the corresponding parse tree node.
     *
     * @throws DataModelException a violation of data model rules
     */
    @Override
    public void validateDataOnExit()
            throws DataModelException {
        /*
         * TODO: perform symbol linking for the imported or included YANG info.
         * TODO: perform symbol resolution for referred YANG entities.
         */
    }

    @Override
    public void detectCollidingChild(String identifierName, YangConstructType dataType)
            throws DataModelException {
        // Asks helper to detect colliding child.
        detectCollidingChildUtil(identifierName, dataType, this);
    }

    @Override
    public void detectSelfCollision(String identifierName, YangConstructType dataType)
            throws DataModelException {
        // Not required as module doesn't have any parent.
    }

    @Override
    public List<YangResolutionInfo> getUnresolvedResolutionList(ResolvableType type) {
        if (type == ResolvableType.YANG_DERIVED_DATA_TYPE) {
            return derivedTypeResolutionList;
        } else if (type == ResolvableType.YANG_USES) {
            return usesResolutionList;
        } else if (type == ResolvableType.YANG_AUGMENT) {
            return augmentResolutionList;
        } else if (type == ResolvableType.YANG_IF_FEATURE) {
            return ifFeatureResolutionList;
        } else if (type == ResolvableType.YANG_LEAFREF) {
            return leafrefResolutionList;
        } else if (type == ResolvableType.YANG_BASE) {
            return baseResolutionList;
        } else {
            return identityrefResolutionList;
        }
    }

    @Override
    public void addToResolutionList(YangResolutionInfo resolutionInfo,
                                    ResolvableType type) {
        if (type == ResolvableType.YANG_DERIVED_DATA_TYPE) {
            derivedTypeResolutionList.add(resolutionInfo);
        } else if (type == ResolvableType.YANG_USES) {
            usesResolutionList.add(resolutionInfo);
        } else if (type == ResolvableType.YANG_IF_FEATURE) {
            ifFeatureResolutionList.add(resolutionInfo);
        } else if (type == ResolvableType.YANG_LEAFREF) {
            leafrefResolutionList.add(resolutionInfo);
        } else if (type == ResolvableType.YANG_BASE) {
            baseResolutionList.add(resolutionInfo);
        } else if (type == ResolvableType.YANG_AUGMENT) {
            augmentResolutionList.add(resolutionInfo);
        } else if (type == ResolvableType.YANG_IDENTITYREF) {
            identityrefResolutionList.add(resolutionInfo);
        }
    }

    @Override
    public void setResolutionList(List<YangResolutionInfo> resolutionList,
                                  ResolvableType type) {
        if (type == ResolvableType.YANG_DERIVED_DATA_TYPE) {
            derivedTypeResolutionList = resolutionList;
        } else if (type == ResolvableType.YANG_USES) {
            usesResolutionList = resolutionList;
        } else if (type == ResolvableType.YANG_IF_FEATURE) {
            ifFeatureResolutionList.add((YangResolutionInfo) resolutionList);
        } else if (type == ResolvableType.YANG_LEAFREF) {
            leafrefResolutionList = resolutionList;
        } else if (type == ResolvableType.YANG_BASE) {
            baseResolutionList = resolutionList;
        } else if (type == ResolvableType.YANG_AUGMENT) {
            augmentResolutionList = resolutionList;
        } else if (type == ResolvableType.YANG_IDENTITYREF) {
            identityrefResolutionList = resolutionList;
        }

    }

    @Override
    public void addReferencesToImportList(Set<YangNode> yangNodeSet)
            throws DataModelException {
        Iterator<YangImport> importInfoIterator = getImportList().iterator();
        // Run through the imported list to add references.
        while (importInfoIterator.hasNext()) {
            YangImport yangImport = importInfoIterator.next();
            yangImport.addReferenceToImport(yangNodeSet);
        }
    }

    @Override
    public void addReferencesToIncludeList(Set<YangNode> yangNodeSet)
            throws DataModelException {
        Iterator<YangInclude> includeInfoIterator = getIncludeList().iterator();
        // Run through the included list to add references.
        while (includeInfoIterator.hasNext()) {
            YangInclude yangInclude = includeInfoIterator.next();
            YangSubModule subModule = null;
            subModule = yangInclude.addReferenceToInclude(yangNodeSet);

            // Check if the referred sub-modules parent is self
            if (!(subModule.getBelongsTo().getModuleNode() == this)) {
                yangInclude.reportIncludeError();
            }
        }
    }
}
