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

import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.translator.tojava.utils.AttributesJavaDataType;

import com.google.common.base.MoreObjects;

/**
 * Maintains the information about individual imports in the generated file.
 */
public class JavaQualifiedTypeInfo implements Comparable<JavaQualifiedTypeInfo> {

    /**
     * Package location where the imported class/interface is defined.
     */
    private String pkgInfo;

    /**
     * Class/interface being referenced.
     */
    private String classInfo;

    /**
     * Default constructor.
     */
    public JavaQualifiedTypeInfo() {
    }

    /**
     * Get the imported package info.
     *
     * @return the imported package info
     */
    public String getPkgInfo() {

        return pkgInfo;
    }

    /**
     * Set the imported package info.
     *
     * @param pkgInfo the imported package info
     */
    public void setPkgInfo(String pkgInfo) {

        this.pkgInfo = pkgInfo;
    }

    /**
     * Get the imported class/interface info.
     *
     * @return the imported class/interface info
     */
    public String getClassInfo() {

        return classInfo;
    }

    /**
     * Set the imported class/interface info.
     *
     * @param classInfo the imported class/interface info
     */
    public void setClassInfo(String classInfo) {

        this.classInfo = classInfo;
    }

    /**
     * Get the import info for an attribute, which needs to be used for code
     * generation for import or for qualified access.
     *
     * @param curNode current data model node for which the java file is being
     *            generated.
     * @param attrType type of attribute being added, it will be null, when the
     *            child class is added as an attribute
     * @param attributeName name of the attribute being added, it will used in
     *            import info for child class.
     * @param isListAttr is the added attribute going to be used as a list
     * @return return the import info for this attribute
     */
    public static JavaQualifiedTypeInfo getQualifiedTypeInfoOfLeafAttribute(YangNode curNode,
            YangType<?> attrType, String attributeName,
            boolean isListAttr) {

        JavaQualifiedTypeInfo importInfo = new JavaQualifiedTypeInfo();

        if (attrType == null) {
            throw new RuntimeException("missing data type of leaf " + attributeName);
        }

        /*
         * Current leaves holder is adding a leaf info as a attribute to the
         * current class.
         */
        String className = AttributesJavaDataType.getJavaImportClass(attrType, isListAttr);
        if (className != null) {
            /*
             * Corresponding to the attribute type a class needs to be imported,
             * since it can be a derived type or a usage of wrapper classes.
             */
            importInfo.setClassInfo(className);
            String classPkg = AttributesJavaDataType.getJavaImportPackage(attrType, isListAttr, className);
            if (classPkg == null) {
                throw new RuntimeException("import package cannot be null when the class is used");
            }
            importInfo.setPkgInfo(classPkg);
        } else {
            /*
             * The attribute does not need a class to be imported, for example
             * built in java types.
             */
            String dataTypeName = AttributesJavaDataType.getJavaDataType(attrType);
            if (dataTypeName == null) {
                throw new RuntimeException("not supported data type");
            }
            importInfo.setClassInfo(dataTypeName);
        }
        return importInfo;
    }

    /**
     * Get the import info for an attribute, which needs to be used for code
     * generation for import or for qualified access.
     *
     * @param curNode current data model node for which the java file is being
     *            generated.
     * @param attributeName name of the attribute being added, it will used in
     *            import info for child class.
     * @param isListAttr is the added attribute going to be used as a list
     * @return return the import info for this attribute
     */
    public static JavaQualifiedTypeInfo getQualifiedTypeInfoOfCurNode(YangNode curNode,
            String attributeName, boolean isListAttr) {

        JavaQualifiedTypeInfo importInfo = new JavaQualifiedTypeInfo();

        if (!(curNode instanceof HasJavaFileInfo)) {
            throw new RuntimeException("missing java file information to get the package details "
                    + "of attribute corresponding to child node");
        }
        /*
         * The scenario when we need to add the child class as an attribute in
         * the current class. The child class is in the package of the current
         * classes package with current classes name.
         */
        importInfo.setClassInfo(attributeName);
        importInfo.setPkgInfo((((HasJavaFileInfo) curNode).getJavaFileInfo().getPackage() + "."
                + ((HasJavaFileInfo) curNode).getJavaFileInfo().getJavaName()).toLowerCase());

        return importInfo;
    }

    /**
     * Get if the attribute needs to be accessed in a qualified manner or not,
     * if it needs to be imported, then the same needs to be done.
     *
     * @param curNode current cache of the data model node for which java file
     *            is bing generated
     * @param importInfo import info for the current attribute being added
     * @return status of the qualified access to the attribute
     */
    public static boolean getIsQualifiedAccessOrAddToImportList(YangNode curNode,
            JavaQualifiedTypeInfo importInfo) {

        boolean isImportPkgEqualCurNodePkg;
        if (!(curNode instanceof HasJavaFileInfo)) {
            throw new RuntimeException("missing java file info for getting the qualified access");
        }
        if (importInfo.getClassInfo().contentEquals(
                ((HasJavaFileInfo) curNode).getJavaFileInfo().getJavaName())) {
            /*
             * if the current class name is same as the attribute class name,
             * then the attribute must be accessed in a qualified manner.
             */
            return true;
        } else if (importInfo.getPkgInfo() != null) {
            /*
             * If the attribute type is having the package info, it is contender
             * for import list and also need to check if it needs to be a
             * qualified access.
             */
            isImportPkgEqualCurNodePkg = isImportPkgEqualCurNodePkg(curNode, importInfo);
            if (!isImportPkgEqualCurNodePkg) {
                /*
                 * If the package of the attribute added is not same as the
                 * current class package, then it must either be imported for
                 * access or it must be a qualified access.
                 */
                if (!(curNode instanceof HasJavaImportData)) {
                    /*
                     * If the current data model node is not supposed to import
                     * data, then this is a usage issue and needs to be fixed.
                     */
                    throw new RuntimeException("Current node needs to support Imports");
                }

                boolean isImportAdded = ((HasJavaImportData) curNode).getJavaImportData()
                        .addImportInfo(curNode, importInfo);
                if (!isImportAdded) {
                    /*
                     * If the attribute type info is not imported, then it must
                     * be a qualified access.
                     */
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Check if the import info is same as the package of the current generated
     * java file.
     *
     * @param curNode Java identifier of the current data model node
     * @param importInfo import info for an attribute
     * @return true if the import info is same as the current nodes package
     *         false otherwise
     */
    public static boolean isImportPkgEqualCurNodePkg(
            YangNode curNode, JavaQualifiedTypeInfo importInfo) {

        if (!(curNode instanceof HasJavaFileInfo)) {
            throw new RuntimeException("missing java file info for the data model node");
        }
        return ((HasJavaFileInfo) curNode).getJavaFileInfo().getPackage()
                .contentEquals(importInfo.getPkgInfo()
                        + "." + importInfo.getClassInfo());
    }

    @Override
    public int hashCode() {

        return Objects.hash(pkgInfo, classInfo);
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }
        if (obj instanceof JavaQualifiedTypeInfo) {
            JavaQualifiedTypeInfo other = (JavaQualifiedTypeInfo) obj;
            return Objects.equals(pkgInfo, other.pkgInfo) &&
                    Objects.equals(classInfo, other.classInfo);
        }
        return false;
    }

    /**
     * check if the import info matches.
     *
     * @param importInfo matched import
     * @return if equal or not
     */
    public boolean exactMatch(JavaQualifiedTypeInfo importInfo) {

        return equals(importInfo)
                && Objects.equals(pkgInfo, importInfo.getPkgInfo())
                && Objects.equals(classInfo, importInfo.getClassInfo());
    }

    @Override
    public String toString() {

        return MoreObjects.toStringHelper(getClass())
                .add("pkgInfo", pkgInfo)
                .add("classInfo", classInfo).toString();
    }

    /**
     * Check that there is no 2 objects with the same class name.
     *
     * @param other compared import info.
     */
    @Override
    public int compareTo(JavaQualifiedTypeInfo other) {

        return getClassInfo().compareTo(other.getClassInfo());
    }

}
