/*
* Copyright 2004,2005 The Apache Software 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.apache.axis2.databinding.utils;


import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.factory.OMXMLBuilderFactory;
import org.apache.axiom.om.util.Base64;
import org.apache.axis2.AxisFault;
import org.apache.axis2.databinding.typemapping.SimpleTypeMapper;
import org.apache.axis2.databinding.utils.reader.ADBXMLStreamReaderImpl;
import org.apache.axis2.engine.ObjectSupplier;
import org.apache.axis2.util.StreamWrapper;
import org.apache.ws.java2wsdl.utils.TypeTable;
import org.codehaus.jam.*;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.*;


public class BeanUtil {

    private static int nsCount = 1;

    /**
     * To Serilize Bean object this method is used, this will create an object array using given
     * bean object
     *
     * @param beanObject
     * @param beanName
     */
    public static XMLStreamReader getPullParser(Object beanObject,
                                                QName beanName,
                                                TypeTable typeTable, boolean qualified) {
        try {
            JamServiceFactory factory = JamServiceFactory.getInstance();
            JamServiceParams jam_service_parms = factory.createServiceParams();
            jam_service_parms.addClassLoader(beanObject.getClass().getClassLoader());
//            beanObject.getClass().isArray()

            jam_service_parms.includeClass(beanObject.getClass().getName());
            JamService service = factory.createService(jam_service_parms);
            JamClassIterator jClassIter = service.getClasses();
            JClass jClass;
            if (jClassIter.hasNext()) {
                jClass = (JClass) jClassIter.next();
            } else {
                throw new AxisFault("No service class found , exception from JAM");
            }
            QName elemntNameSpace = null;
            if (typeTable != null && qualified) {
                QName qNamefortheType = typeTable.getQNamefortheType(beanObject.getClass().getName());
                elemntNameSpace = new QName(qNamefortheType.getNamespaceURI(),
                        "elementName");
            }

            // properties from JAM
            JProperty properties [] = jClass.getDeclaredProperties();
            Arrays.sort(properties);
            BeanInfo beanInfo = Introspector.getBeanInfo(beanObject.getClass());
            PropertyDescriptor [] propDescs = beanInfo.getPropertyDescriptors();
            HashMap propertMap = new HashMap();
            for (int i = 0; i < propDescs.length; i++) {
                PropertyDescriptor propDesc = propDescs[i];
                propertMap.put(propDesc.getName(), propDesc);
            }
            ArrayList object = new ArrayList();
            for (int i = 0; i < properties.length; i++) {
                JProperty property = properties[i];
                PropertyDescriptor propDesc = (PropertyDescriptor) propertMap.get(
                        getCorrectName(property.getSimpleName()));
                if (propDesc == null) {
                    // JAM does bad thing so I need to add this
                    continue;
                }
                Class ptype = propDesc.getPropertyType();
                if (propDesc.getName().equals("class")) {
                    continue;
                }
                if (SimpleTypeMapper.isSimpleType(ptype)) {
                    Object value = propDesc.getReadMethod().invoke(beanObject,
                            null);
                    if (elemntNameSpace != null) {
                        object.add(new QName(elemntNameSpace.getNamespaceURI(),
                                propDesc.getName(), elemntNameSpace.getPrefix()));
                    } else {
                        object.add(new QName(beanName.getNamespaceURI(),
                                propDesc.getName(), beanName.getPrefix()));
                    }
                    object.add(value == null ? null : SimpleTypeMapper.getStringValue(value));
                } else if (ptype.isArray()) {
                    if (SimpleTypeMapper.isSimpleType(ptype.getComponentType())) {
                        Object value = propDesc.getReadMethod().invoke(beanObject,
                                null);
                        int i1 = Array.getLength(value);
                        for (int j = 0; j < i1; j++) {
                            Object o = Array.get(value, j);
                            if (elemntNameSpace != null) {
                                object.add(new QName(elemntNameSpace.getNamespaceURI(),
                                        propDesc.getName(), elemntNameSpace.getPrefix()));
                            } else {
                                object.add(new QName(beanName.getNamespaceURI(),
                                        propDesc.getName(), beanName.getPrefix()));
                            }
                            object.add(o == null ? null : SimpleTypeMapper.getStringValue(o));
                        }
                    } else {
                        Object value [] = (Object[]) propDesc.getReadMethod().invoke(beanObject,
                                null);
                        for (int j = 0; j < value.length; j++) {
                            Object o = value[j];
                            if (elemntNameSpace != null) {
                                object.add(new QName(elemntNameSpace.getNamespaceURI(),
                                        propDesc.getName(), elemntNameSpace.getPrefix()));
                            } else {
                                object.add(new QName(beanName.getNamespaceURI(),
                                        propDesc.getName(), beanName.getPrefix()));
                            }
                            object.add(o);
                        }
                    }

                } else if (SimpleTypeMapper.isArrayList(ptype)) {
                    Object value = propDesc.getReadMethod().invoke(beanObject,
                            null);
                    ArrayList objList = (ArrayList) value;
                    if (objList != null && objList.size() > 0) {
                        //this was given error , when the array.size = 0
                        // and if the array contain simple type , then the ADBPullParser asked
                        // PullParser from That simpel type
                        for (int j = 0; j < objList.size(); j++) {
                            Object o = objList.get(j);
                            if (SimpleTypeMapper.isSimpleType(o)) {
                                if (elemntNameSpace != null) {
                                    object.add(new QName(elemntNameSpace.getNamespaceURI(),
                                            propDesc.getName(), elemntNameSpace.getPrefix()));
                                } else {
                                    object.add(new QName(beanName.getNamespaceURI(),
                                            propDesc.getName(), beanName.getPrefix()));
                                }
                                object.add(o);
                            } else {
                                if (elemntNameSpace != null) {
                                    object.add(new QName(elemntNameSpace.getNamespaceURI(),
                                            propDesc.getName(), elemntNameSpace.getPrefix()));
                                } else {
                                    object.add(new QName(beanName.getNamespaceURI(),
                                            propDesc.getName(), beanName.getPrefix()));
                                }
                                object.add(o);
                            }
                        }

                    }
                } else {
                    if (typeTable != null) {
                        QName qNamefortheType = typeTable.getQNamefortheType(ptype.getName());
                        object.add(new QName(qNamefortheType.getNamespaceURI(),
                                propDesc.getName(), qNamefortheType.getPrefix()));
                    } else {
                        object.add(new QName(beanName.getNamespaceURI(),
                                propDesc.getName(), beanName.getPrefix()));
                    }
                    Object value = propDesc.getReadMethod().invoke(beanObject,
                            null);
                    object.add(value);
                }
            }
            return new ADBXMLStreamReaderImpl(beanName, object.toArray(), null, typeTable,qualified);
        } catch (java.io.IOException e) {
            throw new RuntimeException(e);
        } catch (java.beans.IntrospectionException e) {
            throw new RuntimeException(e);
        } catch (java.lang.reflect.InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (java.lang.IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * to get the pull parser for a given bean object , generate the wrpper element using class name
     *
     * @param beanObject
     */
    public static XMLStreamReader getPullParser(Object beanObject) {
        String className = beanObject.getClass().getName();
        if (className.indexOf(".") > 0) {
            className = className.substring(className.lastIndexOf('.') + 1,
                    className.length());
        }
        return getPullParser(beanObject, new QName(className), null, false);
    }

    public static Object deserialize(Class beanClass,
                                     OMElement beanElement,
                                     ObjectSupplier objectSupplier,
                                     String arrayLocalName)
            throws AxisFault {
        Object beanObj;
        try {
            if (beanClass.isArray()) {
                ArrayList valueList = new ArrayList();
                Class arrayClassType = beanClass.getComponentType();
                Iterator parts = beanElement.getChildElements();
                OMElement omElement;
                while (parts.hasNext()) {
                    Object objValue = parts.next();
                    if (objValue instanceof OMElement) {
                        omElement = (OMElement) objValue;
                        if (!arrayLocalName.equals(omElement.getLocalName())) {
                            continue;
                        }
                        Object obj = deserialize(arrayClassType,
                                omElement,
                                objectSupplier, null);
                        if (obj != null) {
                            valueList.add(obj);
                        }
                    }
                }
                return ConverterUtil.convertToArray(arrayClassType,
                        valueList);
            } else {
                if (SimpleTypeMapper.isSimpleType(beanClass)) {
                    return SimpleTypeMapper.getSimpleTypeObject(beanClass, beanElement);
                }
                HashMap properties = new HashMap();
                BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
                PropertyDescriptor [] propDescs = beanInfo.getPropertyDescriptors();
                for (int i = 0; i < propDescs.length; i++) {
                    PropertyDescriptor proprty = propDescs[i];
                    properties.put(proprty.getName(), proprty);
                }

                beanObj = objectSupplier.getObject(beanClass);
                boolean tuched = false;
                Iterator elements = beanElement.getChildren();
                while (elements.hasNext()) {
                    OMElement parts;
                    Object objValue = elements.next();
                    if (objValue instanceof OMElement) {
                        parts = (OMElement) objValue;
                    } else {
                        continue;
                    }
                    // if parts/@href != null then need to find element with id and deserialize.
                    // before that first check whether we already have it in the hashtable
                    String partsLocalName = parts.getLocalName();
                    PropertyDescriptor prty = (PropertyDescriptor) properties.get(partsLocalName);
                    if (prty != null) {
                        Class parameters = prty.getPropertyType();
                        if (prty.equals("class"))
                            continue;

                        Object partObj;
                        if (SimpleTypeMapper.isSimpleType(parameters)) {
                            partObj = SimpleTypeMapper.getSimpleTypeObject(parameters, parts);
                        } else if (SimpleTypeMapper.isArrayList(parameters)) {
                            partObj = SimpleTypeMapper.getArrayList((OMElement)
                                    parts.getParent(), prty.getName());
                        } else if (parameters.isArray()) {
                            partObj = deserialize(parameters, (OMElement) parts.getParent(),
                                    objectSupplier, prty.getName());
                        } else {
                            partObj = deserialize(parameters, parts, objectSupplier, null);
                        }
                        Object [] parms = new Object[]{partObj};
                        prty.getWriteMethod().invoke(beanObj, parms);
                        tuched = true;
                    }
                }
                if (tuched) {
                    return beanObj;
                } else {
                    return null;
                }
            }
        } catch (IllegalAccessException e) {
            throw new AxisFault("IllegalAccessException : " + e);
        } catch (InvocationTargetException e) {
            throw new AxisFault("InvocationTargetException : " + e);
        } catch (IntrospectionException e) {
            throw new AxisFault("IntrospectionException : " + e);
        }


    }

    public static Object deserialize(Class beanClass,
                                     OMElement beanElement,
                                     MultirefHelper helper,
                                     ObjectSupplier objectSupplier) throws AxisFault {
        Object beanObj;
        try {
            HashMap properties = new HashMap();
            BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
            PropertyDescriptor [] propDescs = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propDescs.length; i++) {
                PropertyDescriptor proprty = propDescs[i];
                properties.put(proprty.getName(), proprty);
            }

            beanObj = objectSupplier.getObject(beanClass);
            Iterator elements = beanElement.getChildren();
            while (elements.hasNext()) {
                Object child = elements.next();
                OMElement parts;
                if (child instanceof OMElement) {
                    parts = (OMElement) child;
                } else {
                    continue;
                }
                String partsLocalName = parts.getLocalName();
                PropertyDescriptor prty = (PropertyDescriptor) properties.get(
                        partsLocalName.toLowerCase());
                if (prty != null) {
                    Class parameters = prty.getPropertyType();
                    if (prty.equals("class"))
                        continue;
                    Object partObj;
                    OMAttribute attr = MultirefHelper.processRefAtt(parts);
                    if (attr != null) {
                        String refId = MultirefHelper.getAttvalue(attr);
                        partObj = helper.getObject(refId);
                        if (partObj == null) {
                            partObj = helper.processRef(parameters, refId, objectSupplier);
                        }
                    } else {
                        partObj = SimpleTypeMapper.getSimpleTypeObject(parameters, parts);
                        if (partObj == null) {
                            partObj = deserialize(parameters, parts, objectSupplier, null);
                        }
                    }
                    Object [] parms = new Object[]{partObj};
                    prty.getWriteMethod().invoke(beanObj, parms);
                }
            }
        } catch (IllegalAccessException e) {
            throw new AxisFault("IllegalAccessException : " + e);
        } catch (InvocationTargetException e) {
            throw new AxisFault("InvocationTargetException : " + e);
        } catch (IntrospectionException e) {
            throw new AxisFault("IntrospectionException : " + e);
        }
        return beanObj;
    }


    /**
     * To get JavaObjects from XML elemnt , the element most of the time contains only one element
     * in that case that element will be converted to the JavaType specified by the javaTypes array
     * The algo is as follows, get the childerns of the response element , and if it conatian more than
     * one element then check the retuen type of that element and conver that to corresponding JavaType
     *
     * @param response  OMElement
     * @param javaTypes Array of JavaTypes
     * @return Array of objects
     * @throws AxisFault
     */
    public static Object [] deserialize(OMElement response,
                                        Object [] javaTypes,
                                        ObjectSupplier objectSupplier) throws AxisFault {
        /*
         * Take the number of parameters in the method and , only take that much of child elements
         * from the OMElement , other are ignore , as an example
         * if the method is , foo(String a , int b)
         * and if the OMElemet
         * <foo>
         *  <arg0>Val1</arg0>
         *  <arg1>Val2</arg1>
         *  <arg2>Val3</arg2>
         *
         * only the val1 and Val2 take into account
         */
        int length = javaTypes.length;
        int count = 0;
        Object [] retObjs = new Object[length];

        /*
        * If the body first child contains , then there can not be any other element withot
        * refs , so I can assume if the first child of the body first element has ref then
        * the message has to handle as mutiref message.
        * as an exmple if the body is like below
        * <foo>
        *  <arg0 href="#0"/>
        * </foo>
        *
        * then there can not be any element without refs , meaning following we are not handling
        * <foo>
        *  <arg0 href="#0"/>
        *  <arg1>absbsbs</arg1>
        * </foo>
        */
        Iterator parts = response.getChildren();
        //to handle multirefs
        //have to check the instanceof
        MultirefHelper helper = new MultirefHelper((OMElement) response.getParent());
        //to support array . if the parameter type is array , then all the omelemnts with that paramtre name
        // has to  get and add to the list
        Class classType;
        String currentLocalName;
        while (parts.hasNext() && count < length) {
            Object objValue = parts.next();
            OMElement omElement;
            if (objValue instanceof OMElement) {
                omElement = (OMElement) objValue;
            } else {
                continue;
            }
            currentLocalName = omElement.getLocalName();
            classType = (Class) javaTypes[count];
            omElement = ProcessElement(classType, omElement, helper, parts,
                    currentLocalName, retObjs, count, objectSupplier);
            while (omElement != null) {
                count ++;
                omElement = ProcessElement((Class) javaTypes[count], omElement,
                        helper, parts, omElement.getLocalName(), retObjs, count, objectSupplier);
            }
            count ++;
        }

        // Ensure that we have at least a zero element array
        for (int i = 0; i < length; i++) {
            Class clazz = (Class) javaTypes[i];
            if (retObjs[i] == null && clazz.isArray()) {
                retObjs[i] = Array.newInstance(clazz.getComponentType(), 0);
            }
        }

        helper.clean();
        return retObjs;
    }

    private static OMElement ProcessElement(Class classType, OMElement omElement,
                                            MultirefHelper helper, Iterator parts,
                                            String currentLocalName,
                                            Object[] retObjs,
                                            int count,
                                            ObjectSupplier objectSupplier) throws AxisFault {
        Object objValue;
        if (classType.isArray()) {
            boolean done = true;
            ArrayList valueList = new ArrayList();
            Class arrayClassType = classType.getComponentType();
            if ("byte".equals(arrayClassType.getName())) {
                retObjs[count] = processObject(omElement, arrayClassType, helper, true, objectSupplier);
                return null;
            } else {
                valueList.add(processObject(omElement, arrayClassType, helper, true, objectSupplier));
            }
            while (parts.hasNext()) {
                objValue = parts.next();
                if (objValue instanceof OMElement) {
                    omElement = (OMElement) objValue;
                } else {
                    continue;
                }
                if (!currentLocalName.equals(omElement.getLocalName())) {
                    done = false;
                    break;
                }
                Object o = processObject(omElement, arrayClassType,
                        helper, true, objectSupplier);
                valueList.add(o);
            }
            retObjs[count] = ConverterUtil.convertToArray(arrayClassType,
                    valueList);
            if (!done) {
                return omElement;
            }
        } else {
            //handling refs
            retObjs[count] = processObject(omElement, classType, helper, false, objectSupplier);
        }
        return null;
    }

    public static Object processObject(OMElement omElement,
                                       Class classType,
                                       MultirefHelper helper,
                                       boolean isArrayType,
                                       ObjectSupplier objectSupplier) throws AxisFault {
        boolean hasRef = false;
        OMAttribute omatribute = MultirefHelper.processRefAtt(omElement);
        String ref = null;
        if (omatribute != null) {
            hasRef = true;
            ref = MultirefHelper.getAttvalue(omatribute);
        }
        if (OMElement.class.isAssignableFrom(classType)) {
            if (hasRef) {
                OMElement elemnt = helper.getOMElement(ref);
                if (elemnt == null) {
                    return helper.processOMElementRef(ref);
                } else {
                    return elemnt;
                }
            } else
                return omElement;
        } else {
            if (hasRef) {
                if (helper.getObject(ref) != null) {
                    return helper.getObject(ref);
                } else {
                    return helper.processRef(classType, ref, objectSupplier);
                }
            } else {
                OMAttribute attribute = omElement.getAttribute(
                        new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi"));
                if (attribute != null) {
                    return null;
                }
                if (SimpleTypeMapper.isSimpleType(classType)) {
                    if (isArrayType && "byte".equals(classType.getName())) {
                        String value = omElement.getText();
                        return Base64.decode(value);
                    } else {
                        return SimpleTypeMapper.getSimpleTypeObject(classType, omElement);
                    }
                } else if (SimpleTypeMapper.isArrayList(classType)) {
                    return SimpleTypeMapper.getArrayList(omElement);
                } else {
                    return BeanUtil.deserialize(classType, omElement, objectSupplier, null);
                }
            }
        }
    }

    public static OMElement getOMElement(QName opName,
                                         Object [] args,
                                         QName partName,
                                         boolean qualifed,
                                         TypeTable typeTable) {
        ArrayList objects;
        objects = new ArrayList();
        int argCount = 0;
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            if (arg == null) {
                objects.add("item" + i);
                objects.add(arg);
                continue;
            }
            //todo if the request parameter has name other than argi (0<i<n) , there should be a
            //way to do that , to solve that problem we need to have RPCRequestParameter
            //note that The value of request parameter can either be simple type or JavaBean
            if (arg instanceof Object[]) {
                Object array [] = (Object[]) arg;
                for (int j = 0; j < array.length; j++) {
                    Object o = array[j];
                    if (o == null) {
                        objects.add("item" + argCount);
                        objects.add(o);
                    } else {
                        if (SimpleTypeMapper.isSimpleType(o)) {
                            objects.add("item" + argCount);
                            objects.add(SimpleTypeMapper.getStringValue(o));
                        } else {
                            objects.add(new QName("item" + argCount));
                            if (o instanceof OMElement) {
                                OMFactory fac = OMAbstractFactory.getOMFactory();
                                OMElement wrappingElement;
                                if (partName == null) {
                                    wrappingElement = fac.createOMElement("item" + argCount, null);
                                    wrappingElement.addChild((OMElement) o);
                                } else {
                                    wrappingElement = fac.createOMElement(partName, null);
                                    wrappingElement.addChild((OMElement) o);
                                }
                                objects.add(wrappingElement);
                            } else {
                                objects.add(o);
                            }
                        }
                    }
                }
            } else {
                if (SimpleTypeMapper.isSimpleType(arg)) {
                    if (partName == null) {
                        objects.add("arg" + argCount);
                    } else {
                        objects.add(partName);
                    }
                    objects.add(SimpleTypeMapper.getStringValue(arg));
                } else {
                    if (partName == null) {
                        objects.add(new QName("arg" + argCount));
                    } else {
                        objects.add(partName);
                    }
                    if (arg instanceof OMElement) {
                        OMFactory fac = OMAbstractFactory.getOMFactory();
                        OMElement wrappingElement;
                        if (partName == null) {
                            wrappingElement = fac.createOMElement("arg" + argCount, null);
                            wrappingElement.addChild((OMElement) arg);
                        } else {
                            wrappingElement = fac.createOMElement(partName, null);
                            wrappingElement.addChild((OMElement) arg);
                        }
                        objects.add(wrappingElement);
                    } else if (arg instanceof byte[]) {
                        objects.add(Base64.encode((byte[]) arg));
                    } else {
                        objects.add(arg);
                    }
                }
            }
            argCount ++;
        }

        XMLStreamReader xr = new ADBXMLStreamReaderImpl(opName, objects.toArray(), null, typeTable, qualifed);

        StreamWrapper parser = new StreamWrapper(xr);
        StAXOMBuilder stAXOMBuilder =
                OMXMLBuilderFactory.createStAXOMBuilder(
                        OMAbstractFactory.getSOAP11Factory(), parser);
        stAXOMBuilder.setDoDebug(true);
        return stAXOMBuilder.getDocumentElement();
    }

    /**
     * @deprecated Please use getUniquePrefix
     */
    public static String getUniquePrifix
            () {
        return "ns" + nsCount++;
    }

    /**
     * increments the namespace counter and returns a new prefix
     *
     * @return unique prefix
     */
    public static String getUniquePrefix
            () {
        return "ns" + nsCount++;
    }

    /**
     * JAM convert first name of an attribute into UpperCase as an example
     * if there is a instance variable called foo in a bean , then Jam give that as Foo
     * so this method is to correct that error
     *
     * @param wrongName
     * @return the right name, using english as the locale for case conversion
     */
    private static String getCorrectName
            (String
                    wrongName) {
        if (wrongName.length() > 1) {
            return wrongName.substring(0, 1).toLowerCase(Locale.ENGLISH)
                    + wrongName.substring(1, wrongName.length());
        } else {
            return wrongName.substring(0, 1).toLowerCase(Locale.ENGLISH);
        }
    }

}
