/*
 * Copyright 2016-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.yms.app.ytb;

import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangIdentity;
import org.onosproject.yangutils.datamodel.YangIdentityRef;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNotification;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangRpc;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.translator.tojava.javamodel.JavaLeafInfoContainer;
import org.onosproject.yms.app.utils.TraversalType;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.onosproject.yms.ydt.YdtContextOperationType;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_MULTI_INSTANCE_NODE;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT16;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT32;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT64;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT8;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT16;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT32;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT8;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yms.app.utils.TraversalType.PARENT;

/**
 * Representation of utility for YANG tree builder.
 */
public final class YtbUtil {

    /**
     * Static attribute for string value having null.
     */
    public static final String STR_NULL = "null";

    /**
     * Static attribute for a dot string.
     */
    public static final String PERIOD = ".";

    private static final int ONE = 1;
    private static final String YANG = "yang";
    private static final String OP_TYPE = "OpType";
    private static final String STR_NONE = "NONE";
    private static final String ENUM_LEAF_IDENTIFIER = "$LeafIdentifier";
    private static final Set<YangDataTypes> PRIMITIVE_TYPES =
            new HashSet<>(Arrays.asList(INT8, INT16, INT32, INT64, UINT8,
                                        UINT16, UINT32, BOOLEAN, EMPTY));
    private static final String TO_STRING = "toString";

    // No instantiation.
    private YtbUtil() {
    }

    /**
     * Returns the object of the node from the node info. Getting object for
     * augment and case differs from other node.
     *
     * @param nodeInfo node info of the holder
     * @param yangNode YANG node of the holder
     * @return object of the parent
     */
    public static Object getParentObjectOfNode(YtbNodeInfo nodeInfo,
                                               YangNode yangNode) {
        Object object;
        if (yangNode instanceof YangCase) {
            object = nodeInfo.getCaseObject();
        } else if (yangNode instanceof YangAugment) {
            object = nodeInfo.getAugmentObject();
        } else {
            object = nodeInfo.getYangObject();
        }
        return object;
    }

    /**
     * Returns the value of an attribute, in a class object. The attribute
     * name is taken from the YANG node java name.
     *
     * @param nodeObj   object of the node
     * @param fieldName name of the attribute
     * @return object of the attribute
     * @throws NoSuchMethodException method not found exception
     */
    public static Object getAttributeOfObject(Object nodeObj, String fieldName)
            throws NoSuchMethodException {
        Class<?> nodeClass = nodeObj.getClass();
        Method getterMethod;
        try {
            getterMethod = nodeClass.getDeclaredMethod(fieldName);
            return getterMethod.invoke(nodeObj);
        } catch (InvocationTargetException | IllegalAccessException e) {
            throw new YtbException(e);
        }
    }

    /**
     * Returns the object of the declared method in parent class by invoking
     * through the child class object.
     *
     * @param childClass child class which inherits the parent class
     * @param methodName name of the declared method
     * @return value of the method
     */
    public static Object getAttributeFromInheritance(Object childClass,
                                                     String methodName) {
        Class<?> parentClass = childClass.getClass().getSuperclass();
        Method getterMethod;
        try {
            getterMethod = parentClass.getDeclaredMethod(methodName);
            return getterMethod.invoke(childClass);
        } catch (InvocationTargetException | NoSuchMethodException |
                IllegalAccessException e) {
            throw new YtbException(e);
        }
    }

    /**
     * Returns interface class from an implementation class object.
     *
     * @param obj implementation class object
     * @return interface class
     */
    public static Class<?> getInterfaceClassFromImplClass(Object obj) {
        Class<?>[] interfaces = obj.getClass().getInterfaces();
        if (interfaces.length > ONE) {
            // TODO: Need to handle when impl class has more than one interface.
            throw new YtbException("Implementation class having more than one" +
                                           " interface is not handled");
        }
        return interfaces[0];
    }

    /**
     * Returns the operation type value for a class object. If the operation
     * type is not set, then none type is returned.
     *
     * @param nodeObj  node object
     * @param typeName data type name
     * @return operation type of the class
     */
    public static YdtContextOperationType getNodeOpType(Object nodeObj,
                                                        String typeName) {
        Object opTypeObj;
        try {
            opTypeObj = getAttributeOfObject(nodeObj, typeName);
        } catch (NoSuchMethodException e) {
            return YdtContextOperationType.valueOf(STR_NONE);
        }
        String opTypeValue = String.valueOf(opTypeObj);
        if (opTypeValue.equals(STR_NULL)) {
            return null;
        }
        return YdtContextOperationType.valueOf(opTypeValue);
    }

    /**
     * Returns true, if data type of leaf is primitive data type; false
     * otherwise.
     *
     * @param yangType leaf type
     * @return true if data type is primitive; false otherwise
     */
    public static boolean isTypePrimitive(YangType yangType) {
        if (yangType.getDataType() == LEAFREF) {
            YangLeafRef leafRef =
                    (YangLeafRef) yangType.getDataTypeExtendedInfo();
            return isPrimitiveDataType(leafRef.getEffectiveDataType()
                                               .getDataType());
        }
        return isPrimitiveDataType(yangType.getDataType());
    }

    /**
     * Returns the registered class from the YSR of the module node where
     * augment is present.
     *
     * @param curNode  current augment node
     * @param registry schema registry
     * @return class loader of module
     */
    public static Class<?> getClassLoaderForAugment(
            YangNode curNode, YangSchemaRegistry registry) {
        YangNode moduleNode = curNode.getParent();
        String moduleName = moduleNode.getJavaClassNameOrBuiltInType();
        String modulePackage = moduleNode.getJavaPackage();
        return registry.getRegisteredClass(moduleNode
        );
    }

    /**
     * Returns the string true, if the leaf data is actually set; false
     * otherwise.
     *
     * @param holder     leaf holder
     * @param nodeObj    object if the node
     * @param javaName   java name of the leaf
     * @param methodName getter method name
     * @return string value of the boolean method
     * @throws NoSuchMethodException if the method is not present
     */
    public static String isValueOrSelectLeafSet(YangSchemaNode holder, Object nodeObj,
                                                String javaName, String methodName)
            throws NoSuchMethodException {

        Class<?> nodeClass = nodeObj.getClass();

        // Appends the enum inner package to the interface class package.
        String enumPackage = holder.getJavaPackage() + PERIOD +
                getCapitalCase(holder.getJavaClassNameOrBuiltInType()) +
                ENUM_LEAF_IDENTIFIER;

        ClassLoader classLoader = nodeClass.getClassLoader();
        Class leafEnum;
        try {
            leafEnum = classLoader.loadClass(enumPackage);
            Method getterMethod = nodeClass.getMethod(methodName, leafEnum);
            // Gets the value of the enum.
            Enum<?> value = Enum.valueOf(leafEnum, javaName.toUpperCase());
            // Invokes the method with the value of enum as param.
            return String.valueOf(getterMethod.invoke(nodeObj, value));
        } catch (IllegalAccessException | InvocationTargetException |
                ClassNotFoundException e) {
            throw new YtbException(e);
        }
    }

    /**
     * Returns the string value from the respective data types of the
     * leaf/leaf-list.
     *
     * @param holder    leaf/leaf-list holder
     * @param holderObj leaf/leaf-list holder object
     * @param name      leaf/leaf-list name
     * @param fieldObj  object of the leaf/leaf-list field
     * @param dataType  type of the leaf/leaf-list
     * @return string value from the type
     */
    public static String getStringFromType(YangSchemaNode holder, Object holderObj,
                                           String name, Object fieldObj, YangType dataType) {

        if (fieldObj == null) {
            throw new YtbException("Value of " + holder.getName() + " is null");
        }

        YangDataTypes type = dataType.getDataType();
        switch (type) {
            case INT8:
            case INT16:
            case INT32:
            case INT64:
            case UINT8:
            case UINT16:
            case UINT32:
            case UINT64:
            case EMPTY:
            case STRING:
            case DECIMAL64:
            case INSTANCE_IDENTIFIER:
            case DERIVED:
            case UNION:
            case ENUMERATION:
            case BOOLEAN:
                return String.valueOf(fieldObj).trim();

            case BITS:
                return getBitsValue(holder, holderObj, name, fieldObj).trim();

            case BINARY:
                return Base64.getEncoder().encodeToString((byte[]) fieldObj);

            case IDENTITYREF:
                YangIdentityRef ir =
                        (YangIdentityRef) dataType.getDataTypeExtendedInfo();
                if (ir.isInGrouping()) {
                    return String.valueOf(fieldObj).trim();
                }
                return getIdentityRefValue(fieldObj, ir, holderObj);

            case LEAFREF:
                YangLeafRef leafRef =
                        (YangLeafRef) dataType.getDataTypeExtendedInfo();
                return getStringFromType(holder, holderObj, name, fieldObj,
                                         leafRef.getEffectiveDataType());

            default:
                throw new YtbException("Unsupported data type. Cannot be " +
                                               "processed.");
        }
    }

    /**
     * Returns the string values for the data type bits.
     *
     * @param holder    leaf/leaf-list holder
     * @param holderObj leaf/leaf-list holder object
     * @param name      leaf/leaf-list name
     * @param fieldObj  object of the leaf/leaf-list field
     * @return string value for bits type
     */
    private static String getBitsValue(YangSchemaNode holder, Object holderObj,
                                       String name, Object fieldObj) {

        Class<?> holderClass = holderObj.getClass();
        String interfaceName = holder.getJavaClassNameOrBuiltInType();
        String className = interfaceName.toLowerCase() + PERIOD +
                getCapitalCase(name);
        String pkgName = holder.getJavaPackage() + PERIOD + className;
        ClassLoader classLoader = holderClass.getClassLoader();

        Class<?> bitClass;
        try {
            bitClass = classLoader.loadClass(pkgName);
            Method getterMethod = bitClass.getDeclaredMethod(
                    TO_STRING, fieldObj.getClass());
            return String.valueOf(getterMethod.invoke(null, fieldObj));
        } catch (ClassNotFoundException | NoSuchMethodException |
                InvocationTargetException | IllegalAccessException e) {
            throw new YtbException(e);
        }
    }

    /**
     * Returns the string value of the type identity-ref.
     *
     * @param fieldObj  object of the leaf/leaf-list field
     * @param ir        YANG identity ref
     * @param holderObj leaf/leaf-list holder object
     * @return string value for identity ref type
     */
    private static String getIdentityRefValue(Object fieldObj, YangIdentityRef ir,
                                              Object holderObj) {

        YangIdentity id = ir.getReferredIdentity();
        String idName = id.getJavaClassNameOrBuiltInType();
        String idPkg = id.getJavaPackage() + PERIOD + getCapitalCase(idName);
        String methodName = idName + getCapitalCase(TO_STRING);

        Class<?> holderClass = holderObj.getClass();
        ClassLoader classLoader = holderClass.getClassLoader();
        Class<?> idClass;
        try {
            idClass = classLoader.loadClass(idPkg);
            Method method = idClass.getDeclaredMethod(methodName, null);
            return String.valueOf(method.invoke(fieldObj, null)).trim();
        } catch (ClassNotFoundException | NoSuchMethodException |
                InvocationTargetException | IllegalAccessException e) {
            throw new YtbException(e);
        }
    }

    /**
     * Returns true, if the data type is primitive; false otherwise.
     *
     * @param dataType data type
     * @return true if the data type is primitive; false otherwise
     */
    private static boolean isPrimitiveDataType(YangDataTypes dataType) {
        return PRIMITIVE_TYPES.contains(dataType);
    }

    /**
     * Returns true, if processing of the node is not required; false otherwise.
     * For the nodes such as notification, RPC, augment there is a different
     * flow, so these nodes are skipped in normal conditions.
     *
     * @param yangNode node to be checked
     * @return true if node processing is not required; false otherwise.
     */
    public static boolean isNonProcessableNode(YangNode yangNode) {
        return yangNode != null && (yangNode instanceof YangNotification) ||
                (yangNode instanceof YangRpc) || (yangNode instanceof YangAugment);
    }

    /**
     * Returns true, if multi instance node; false otherwise.
     *
     * @param yangNode YANG node
     * @return true, if multi instance node; false otherwise.
     */
    public static boolean isMultiInstanceNode(YangNode yangNode) {
        return yangNode.getYangSchemaNodeType() == YANG_MULTI_INSTANCE_NODE;
    }

    /**
     * Returns true, if augment node; false otherwise.
     *
     * @param yangNode YANG node
     * @return true, if augment node; false otherwise.
     */
    public static boolean isAugmentNode(YangNode yangNode) {
        return yangNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE;
    }

    /**
     * Returns string for throwing error when empty object is given as input
     * to YTB.
     *
     * @param objName name of the object
     * @return error message
     */
    public static String emptyObjErrMsg(String objName) {
        return "The " + objName + " given for tree creation cannot be null";
    }

    /**
     * Returns the java name for the nodes, leaf/leaf-list.
     *
     * @param node YANG node
     * @return node java name
     */
    public static String getJavaName(Object node) {
        return ((JavaLeafInfoContainer) node).getJavaName(null);
    }

    /**
     * Returns true, if the list is not null and non-empty; false otherwise.
     *
     * @param c collection object
     * @return true, if the list is not null and non-empty; false otherwise
     */
    public static boolean nonEmpty(Collection<?> c) {
        return c != null && !c.isEmpty();
    }

    /**
     * Returns true, if the string is not null and non-empty; false otherwise.
     *
     * @param str string value
     * @return true, if the string is not null and non-empty; false otherwise.
     */
    public static boolean nonEmpty(String str) {
        return str != null && !str.isEmpty();
    }

    /**
     * Returns true when the node processing of RPC and notification is
     * completed; false otherwise. For RPC and notification, processing of
     * other nodes are invalid, so once node gets completed, it must be stopped.
     *
     * @param curNode      current node
     * @param curTraversal current traversal of the node
     * @return true, if the node processing is completed; false otherwise.
     */
    public static boolean isNodeProcessCompleted(
            YangNode curNode, TraversalType curTraversal) {
        return (curTraversal == PARENT &&
                curNode instanceof YangNotification) ||
                curNode instanceof YangOutput;
    }

    /**
     * Returns the name of the operation type variable from the yang name.
     *
     * @param curNode YANG node
     * @return name of operation type
     */
    public static String getOpTypeName(YangNode curNode) {
        return YANG + getCapitalCase(curNode.getJavaClassNameOrBuiltInType()) +
                OP_TYPE;
    }
}
