/*
 * 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.yms.app.yob;

import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
import org.onosproject.yangutils.datamodel.YangBinary;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
import org.onosproject.yms.app.yob.exception.YobExceptions;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;

import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yms.app.ydt.AppType.YOB;
import static org.onosproject.yms.app.yob.YobConstants.DATA_TYPE_NOT_SUPPORT;
import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CONSTRUCTOR;
import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
import static org.onosproject.yms.app.yob.YobConstants.OF;
import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
import static org.onosproject.yms.app.yob.YobWorkBench.getQualifiedDefaultClassName;

/**
 * Represents a YANG object builder handler to process the ydt content and
 * build yang object.
 */
abstract class YobHandler {

    private static final Logger log = LoggerFactory.getLogger(YobHandler.class);

    /**
     * reference to YANG schema registry.
     */
    private YangSchemaRegistry registry;

    /**
     * Creates a YANG builder object.
     *
     * @param curYdtNode  ydtExtendedContext is used to get
     *                    application related information maintained
     *                    in YDT
     * @param rootYdtNode ydtRootNode is refers to module node
     * @param registry    registry
     */
    public void createYangBuilderObject(YdtExtendedContext curYdtNode,
                                        YdtExtendedContext rootYdtNode,
                                        YangSchemaRegistry registry) {
        String setterName = null;
        YangSchemaNode node = curYdtNode.getYangSchemaNode();

        String qualName = getQualifiedDefaultClassName(node);
        ClassLoader classLoader = getClassLoader(registry,
                                                 qualName,
                                                 curYdtNode, rootYdtNode);

        if (curYdtNode != rootYdtNode) {
            setterName = node.getJavaAttributeName();
        }

        Object builderObject = new YobWorkBench(node, classLoader,
                                                qualName, setterName);

        curYdtNode.addAppInfo(YOB, builderObject);
    }

    /**
     * Sets the YANG built object in corresponding parent class method.
     *
     * @param ydtNode        ydtExtendedContext is used to get application
     *                       related information maintained in YDT
     * @param schemaRegistry YANG schema registry
     */
    public void setObjectInParent(YdtExtendedContext ydtNode,
                                  YangSchemaRegistry schemaRegistry) {
    }

    /**
     * Builds the object.
     *
     * @param ydtNode        ydtExtendedContext is used to get
     *                       application related
     *                       information maintained in YDT
     * @param ydtRootNode    ydtRootNode
     * @param schemaRegistry YANG schema registry
     */
    public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
                                       YdtExtendedContext ydtRootNode,
                                       YangSchemaRegistry schemaRegistry) {
        YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
        yobWorkBench.buildObject(ydtNode, ydtRootNode);
    }

    /**
     * This method is used to set data from string value in parent method.
     *
     * @param type                refers to YANG type
     * @param leafValue           leafValue argument is used to set the value
     *                            in method
     * @param parentSetterMethod  Invokes the underlying method represented
     *                            by this parentSetterMethod
     * @param parentBuilderObject the parentBuilderObject is to invoke the
     *                            underlying method
     * @param ydtExtendedContext  ydtExtendedContext is used to get
     *                            application related
     *                            information maintained in YDT
     * @throws InvocationTargetException throws InvocationTargetException
     * @throws IllegalAccessException    throws IllegalAccessException
     * @throws NoSuchMethodException     throws NoSuchMethodException
     */
    void setDataFromStringValue(YangType<?> type, String leafValue,
                                Method parentSetterMethod,
                                Object parentBuilderObject,
                                YdtExtendedContext ydtExtendedContext)
            throws InvocationTargetException, IllegalAccessException,
            NoSuchMethodException {
        switch (type.getDataType()) {
            case INT8: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          Byte.parseByte(leafValue));
                break;
            }
            case UINT8:
            case INT16: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          Short.parseShort(leafValue));
                break;
            }
            case UINT16:
            case INT32: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          Integer.parseInt(leafValue));
                break;
            }
            case UINT32:
            case INT64: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          Long.parseLong(leafValue));
                break;
            }
            case UINT64: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          new BigInteger(leafValue));
                break;
            }
            case EMPTY:
            case BOOLEAN: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          Boolean.parseBoolean(leafValue));
                break;
            }
            case STRING: {
                parentSetterMethod.invoke(parentBuilderObject, leafValue);
                break;
            }
            case BINARY: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          new YangBinary(leafValue));
                break;
            }
            case BITS: {
                //TODO
                break;
            }
            case DECIMAL64: {
                parentSetterMethod.invoke(parentBuilderObject,
                                          new BigDecimal(leafValue));
                break;
            }
            case DERIVED: {
                parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
                                     parentBuilderObject, leafValue, false);
                break;
            }
            case UNION: {
                // TODO
                break;
            }
            case LEAFREF: {
                // TODO
                break;
            }
            case ENUMERATION: {
                parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
                                     parentBuilderObject, leafValue, true);
                break;
            }
            default: {
                log.error(DATA_TYPE_NOT_SUPPORT);
            }
        }
    }

    /**
     * To set data into parent setter method from string value for derived type.
     *
     * @param leafValue           leafValue argument is used to set the value
     *                            in method
     * @param parentSetterMethod  Invokes the underlying method represented
     *                            by this parentSetterMethod
     * @param parentBuilderObject the parentBuilderObject is to invoke the
     *                            underlying method
     * @param ydtExtendedContext  ydtExtendedContext is used to get
     *                            application related
     *                            information maintained in YDT
     * @param isEnum              isEnum parameter is used to check whether
     *                            type is enum or derived
     *                            information maintained in YDT
     * @throws InvocationTargetException throws InvocationTargetException
     * @throws IllegalAccessException    throws IllegalAccessException
     * @throws NoSuchMethodException     throws NoSuchMethodException
     */
    private void parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
                                      Method parentSetterMethod,
                                      Object parentBuilderObject,
                                      String leafValue, boolean isEnum)
            throws InvocationTargetException, IllegalAccessException,
            NoSuchMethodException {
        Class<?> childSetClass = null;
        Constructor<?> childConstructor = null;
        Object childValue = null;
        Object childObject = null;
        Method childMethod = null;

        YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
        String packageName = yangJavaModule.getJavaPackage();
        String className = getCapitalCase(
                yangJavaModule.getJavaClassNameOrBuiltInType());
        String qualifiedClassName = packageName + PERIOD + className;
        ClassLoader classLoader = getClassLoader(registry,
                                                 qualifiedClassName,
                                                 ydtExtendedContext, null);
        try {
            childSetClass = classLoader.loadClass(qualifiedClassName);
        } catch (ClassNotFoundException e) {
            log.error(FAIL_TO_LOAD_CLASS + packageName + PERIOD + className);
        }
        if (!isEnum) {

            if (childSetClass != null) {
                childConstructor = childSetClass.getDeclaredConstructor();
            }

            if (childConstructor != null) {
                childConstructor.setAccessible(true);
            }
            try {
                if (childConstructor != null) {
                    childObject = childConstructor.newInstance();
                }
            } catch (InstantiationException e) {
                log.error(FAIL_TO_LOAD_CONSTRUCTOR + className);
            }
            if (childSetClass != null) {
                childMethod = childSetClass
                        .getDeclaredMethod(FROM_STRING, String.class);
            }
        } else {
            if (childSetClass != null) {
                childMethod = childSetClass.getDeclaredMethod(OF, String.class);
            }
            //leafValue = JavaIdentifierSyntax.getEnumJavaAttribute(leafValue);
            //leafValue = leafValue.toUpperCase();
        }
        if (childMethod != null) {
            childValue = childMethod.invoke(childObject, leafValue);
        }

        parentSetterMethod.invoke(parentBuilderObject, childValue);
    }

    /**
     * Updates class loader for all the classes.
     *
     * @param registry           YANG schema registry
     * @param curNode            YDT context
     * @param qualifiedClassName qualified class name
     * @return current class loader
     */
    private ClassLoader getClassLoader(YangSchemaRegistry registry,
                                       String qualifiedClassName,
                                       YdtExtendedContext curNode,
                                       YdtExtendedContext context) {

        if (context != null && curNode == context) {
            YangSchemaNode yangSchemaNode = curNode.getYangSchemaNode();
            while (!(yangSchemaNode instanceof RpcNotificationContainer)) {
                curNode = (YdtExtendedContext) curNode.getParent();
                if (curNode == null) {
                    throw new YobExceptions("Invalid YANG data tree");
                }
                yangSchemaNode = curNode.getYangSchemaNode();
            }

            Class<?> regClass = registry.getRegisteredClass(yangSchemaNode,
                                                            qualifiedClassName);
            return regClass.getClassLoader();
        } else {
            YdtExtendedContext parent =
                    (YdtExtendedContext) curNode.getParent();
            YobWorkBench parentBuilderContainer =
                    (YobWorkBench) parent.getAppInfo(YOB);
            Object parentObj =
                    parentBuilderContainer.getParentBuilder(curNode, registry);
            return parentObj.getClass().getClassLoader();
        }
    }

    /**
     * Returns the YANG schema registry.
     *
     * @return registry YANG schema registry
     */
    public YangSchemaRegistry getRegistry() {
        return registry;
    }

    /**
     * Sets the YANG schema registry.
     *
     * @param registry YANG schema registry
     */
    public void setRegistry(YangSchemaRegistry registry) {
        this.registry = registry;
    }
}
