/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.struts2.json;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.json.annotations.JSON;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Isolate the process of populating JSON objects from the Interceptor class
 * itself.
 */
public class JSONPopulator {

    private static final Logger LOG = LogManager.getLogger(JSONPopulator.class);

    private String dateFormat = JSONUtil.RFC3339_FORMAT;

    public JSONPopulator() {
    }

    public JSONPopulator(String dateFormat) {
        this.dateFormat = dateFormat;
    }

    public String getDateFormat() {
        return dateFormat;
    }

    public void setDateFormat(String dateFormat) {
        this.dateFormat = dateFormat;
    }

    @SuppressWarnings("unchecked")
    public void populateObject(Object object, final Map elements) throws IllegalAccessException,
            InvocationTargetException, NoSuchMethodException, IntrospectionException,
            IllegalArgumentException, JSONException, InstantiationException {
        Class clazz = object.getClass();

        BeanInfo info = Introspector.getBeanInfo(clazz);
        PropertyDescriptor[] props = info.getPropertyDescriptors();

        // iterate over class fields
        for (PropertyDescriptor prop : props) {
            String name = prop.getName();

            if (elements.containsKey(name)) {
                Object value = elements.get(name);
                Method method = prop.getWriteMethod();

                if (method != null) {
                    JSON json = method.getAnnotation(JSON.class);
                    if ((json != null) && !json.deserialize()) {
                        continue;
                    }

                    // use only public setters
                    if (Modifier.isPublic(method.getModifiers())) {
                        Class[] paramTypes = method.getParameterTypes();
                        Type[] genericTypes = method.getGenericParameterTypes();

                        if (paramTypes.length == 1) {
                            Object convertedValue = this.convert(paramTypes[0], genericTypes[0], value, method);
                            method.invoke(object, new Object[] { convertedValue });
                        }
                    }
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public Object convert(Class clazz, Type type, Object value, Method method)
            throws IllegalArgumentException, JSONException, IllegalAccessException,
            InvocationTargetException, InstantiationException, NoSuchMethodException, IntrospectionException {

        if (value == null) {
            // if it is a java primitive then get a default value, otherwise
            // leave it as null
            return clazz.isPrimitive() ? convertPrimitive(clazz, value, method) : null;
        } else if (isJSONPrimitive(clazz))
            return convertPrimitive(clazz, value, method);
        else if (Collection.class.isAssignableFrom(clazz))
            return convertToCollection(clazz, type, value, method);
        else if (Map.class.isAssignableFrom(clazz))
            return convertToMap(clazz, type, value, method);
        else if (clazz.isArray())
            return convertToArray(clazz, type, value, method);
        else if (value instanceof Map) {
            // nested bean
            Object convertedValue = clazz.newInstance();
            this.populateObject(convertedValue, (Map) value);
            return convertedValue;
        } else if (BigDecimal.class.equals(clazz)) {
            return new BigDecimal(value.toString());
        } else if (BigInteger.class.equals(clazz)) {
            return new BigInteger(value.toString());
        } else
            throw new JSONException("Incompatible types for property " + method.getName());
    }

    private static boolean isJSONPrimitive(Class clazz) {
        return clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Date.class)
                || clazz.equals(Boolean.class) || clazz.equals(Byte.class) || clazz.equals(Character.class)
                || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Integer.class)
                || clazz.equals(Long.class) || clazz.equals(Short.class) || clazz.equals(Locale.class)
                || clazz.isEnum();
    }

    @SuppressWarnings("unchecked")
    private Object convertToArray(Class clazz, Type type, Object value, Method accessor)
            throws JSONException, IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, InstantiationException, NoSuchMethodException, IntrospectionException {
        if (value == null)
            return null;
        else if (value instanceof List) {
            Class arrayType = clazz.getComponentType();
            List values = (List) value;
            Object newArray = Array.newInstance(arrayType, values.size());

            // create an object for each element
            for (int j = 0; j < values.size(); j++) {
                Object listValue = values.get(j);

                if (arrayType.equals(Object.class)) {
                    // Object[]
                    Array.set(newArray, j, listValue);
                } else if (isJSONPrimitive(arrayType)) {
                    // primitive array
                    Array.set(newArray, j, this.convertPrimitive(arrayType, listValue, accessor));
                } else if (listValue instanceof Map) {
                    // array of other class
                    Object newObject;
                    if (Map.class.isAssignableFrom(arrayType)) {
                        newObject = convertToMap(arrayType, type, listValue, accessor);
                    } else if (List.class.isAssignableFrom(arrayType)) {
                        newObject = convertToCollection(arrayType, type, listValue, accessor);
                    } else {
                        newObject = arrayType.newInstance();
                        this.populateObject(newObject, (Map) listValue);
                    }

                    Array.set(newArray, j, newObject);
                } else
                    throw new JSONException("Incompatible types for property " + accessor.getName());
            }

            return newArray;
        } else
            throw new JSONException("Incompatible types for property " + accessor.getName());
    }

    @SuppressWarnings("unchecked")
    private Object convertToCollection(Class clazz, Type type, Object value, Method accessor)
            throws JSONException, IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, InstantiationException, NoSuchMethodException, IntrospectionException {
        if (value == null)
            return null;
        else if (value instanceof List) {
            Class itemClass = Object.class;
            Type itemType = null;
            if ((type != null) && (type instanceof ParameterizedType)) {
                ParameterizedType ptype = (ParameterizedType) type;
                itemType = ptype.getActualTypeArguments()[0];
                if (itemType.getClass().equals(Class.class)) {
                    itemClass = (Class) itemType;
                } else {
                    itemClass = (Class) ((ParameterizedType) itemType).getRawType();
                }
            }
            List values = (List) value;

            Collection newCollection = null;
            try {
                newCollection = (Collection) clazz.newInstance();
            } catch (InstantiationException ex) {
                // fallback if clazz represents an interface or abstract class
                if (SortedSet.class.isAssignableFrom(clazz)) {
                    newCollection = new TreeSet();
                } else if (Set.class.isAssignableFrom(clazz)) {
                    newCollection = new HashSet();
                } else if (Queue.class.isAssignableFrom(clazz)) {
                    newCollection = new ArrayDeque();
                } else {
                    newCollection = new ArrayList();
                }
            }

            // create an object for each element
            for (Object listValue : values) {

                if (itemClass.equals(Object.class)) {
                    // Object[]
                    newCollection.add(listValue);
                } else if (isJSONPrimitive(itemClass)) {
                    // primitive array
                    newCollection.add(this.convertPrimitive(itemClass, listValue, accessor));
                } else if (Map.class.isAssignableFrom(itemClass)) {
                    Object newObject = convertToMap(itemClass, itemType, listValue, accessor);
                    newCollection.add(newObject);
                } else if (List.class.isAssignableFrom(itemClass)) {
                    Object newObject = convertToCollection(itemClass, itemType, listValue, accessor);
                    newCollection.add(newObject);
                } else if (listValue instanceof Map) {
                    // array of beans
                    Object newObject = itemClass.newInstance();
                    this.populateObject(newObject, (Map) listValue);
                    newCollection.add(newObject);
                } else
                    throw new JSONException("Incompatible types for property " + accessor.getName());
            }

            return newCollection;
        } else
            throw new JSONException("Incompatible types for property " + accessor.getName());
    }

    @SuppressWarnings("unchecked")
    private Object convertToMap(Class clazz, Type type, Object value, Method accessor) throws JSONException,
            IllegalArgumentException, IllegalAccessException, InvocationTargetException,
            InstantiationException, NoSuchMethodException, IntrospectionException {
        if (value == null)
            return null;
        else if (value instanceof Map) {
            Class itemClass = Object.class;
            Type itemType = null;
            if ((type != null) && (type instanceof ParameterizedType)) {
                ParameterizedType ptype = (ParameterizedType) type;
                itemType = ptype.getActualTypeArguments()[1];
                if (itemType.getClass().equals(Class.class)) {
                    itemClass = (Class) itemType;
                } else {
                    itemClass = (Class) ((ParameterizedType) itemType).getRawType();
                }
            }
            Map values = (Map) value;

            Map newMap;
            try {
                newMap = (Map) clazz.newInstance();
            } catch (InstantiationException ex) {
                // fallback if clazz represents an interface or abstract class
                newMap = new HashMap();
            }

            // create an object for each element
            for (Object next : values.entrySet()) {
                Map.Entry entry = (Map.Entry) next;
                String key = (String) entry.getKey();
                Object v = entry.getValue();

                if (itemClass.equals(Object.class)) {
                    // String, Object
                    newMap.put(key, v);
                } else if (isJSONPrimitive(itemClass)) {
                    // primitive map
                    newMap.put(key, this.convertPrimitive(itemClass, v, accessor));
                } else if (Map.class.isAssignableFrom(itemClass)) {
                    Object newObject = convertToMap(itemClass, itemType, v, accessor);
                    newMap.put(key, newObject);
                } else if (List.class.isAssignableFrom(itemClass)) {
                    Object newObject = convertToCollection(itemClass, itemType, v, accessor);
                    newMap.put(key, newObject);
                } else if (v instanceof Map) {
                    // map of beans
                    Object newObject = itemClass.newInstance();
                    this.populateObject(newObject, (Map) v);
                    newMap.put(key, newObject);
                } else
                    throw new JSONException("Incompatible types for property " + accessor.getName());
            }

            return newMap;
        } else
            throw new JSONException("Incompatible types for property " + accessor.getName());
    }

    /**
     * Converts numbers to the desired class, if possible
     * 
     * @throws JSONException
     */
    @SuppressWarnings("unchecked")
    private Object convertPrimitive(Class clazz, Object value, Method method) throws JSONException {
        if (value == null) {
            if (Short.TYPE.equals(clazz) || Short.class.equals(clazz))
                return (short) 0;
            else if (Byte.TYPE.equals(clazz) || Byte.class.equals(clazz))
                return (byte) 0;
            else if (Integer.TYPE.equals(clazz) || Integer.class.equals(clazz))
                return 0;
            else if (Long.TYPE.equals(clazz) || Long.class.equals(clazz))
                return 0L;
            else if (Float.TYPE.equals(clazz) || Float.class.equals(clazz))
                return 0f;
            else if (Double.TYPE.equals(clazz) || Double.class.equals(clazz))
                return 0d;
            else if (Boolean.TYPE.equals(clazz) || Boolean.class.equals(clazz))
                return Boolean.FALSE;
            else
                return null;
        } else if (value instanceof Number) {
            Number number = (Number) value;

            if (Short.TYPE.equals(clazz))
                return number.shortValue();
            else if (Short.class.equals(clazz))
                return number.shortValue();
            else if (Byte.TYPE.equals(clazz))
                return number.byteValue();
            else if (Byte.class.equals(clazz))
                return number.byteValue();
            else if (Integer.TYPE.equals(clazz))
                return number.intValue();
            else if (Integer.class.equals(clazz))
                return number.intValue();
            else if (Long.TYPE.equals(clazz))
                return number.longValue();
            else if (Long.class.equals(clazz))
                return number.longValue();
            else if (Float.TYPE.equals(clazz))
                return number.floatValue();
            else if (Float.class.equals(clazz))
                return number.floatValue();
            else if (Double.TYPE.equals(clazz))
                return number.doubleValue();
            else if (Double.class.equals(clazz))
                return number.doubleValue();
            else if (String.class.equals(clazz))
                return value.toString();
        } else if (clazz.equals(Date.class)) {
            try {
                JSON json = method.getAnnotation(JSON.class);

                DateFormat formatter = new SimpleDateFormat(
                        (json != null) && (json.format().length() > 0) ? json.format() : this.dateFormat);
                return formatter.parse((String) value);
            } catch (ParseException e) {
                LOG.error("Unable to parse date from: {}", value, e);
                throw new JSONException("Unable to parse date from: " + value);
            }
        } else if (clazz.isEnum()) {
            String sValue = (String) value;
            return Enum.valueOf(clazz, sValue);
        } else if (value instanceof String) {
            String sValue = (String) value;
            if (Boolean.TYPE.equals(clazz))
                return Boolean.parseBoolean(sValue);
            else if (Boolean.class.equals(clazz))
                return Boolean.valueOf(sValue);
            else if (Short.TYPE.equals(clazz))
                return Short.parseShort(sValue);
            else if (Short.class.equals(clazz))
                return Short.valueOf(sValue);
            else if (Byte.TYPE.equals(clazz))
                return Byte.parseByte(sValue);
            else if (Byte.class.equals(clazz))
                return Byte.valueOf(sValue);
            else if (Integer.TYPE.equals(clazz))
                return Integer.parseInt(sValue);
            else if (Integer.class.equals(clazz))
                return Integer.valueOf(sValue);
            else if (Long.TYPE.equals(clazz))
                return Long.parseLong(sValue);
            else if (Long.class.equals(clazz))
                return Long.valueOf(sValue);
            else if (Float.TYPE.equals(clazz))
                return Float.parseFloat(sValue);
            else if (Float.class.equals(clazz))
                return Float.valueOf(sValue);
            else if (Double.TYPE.equals(clazz))
                return Double.parseDouble(sValue);
            else if (Double.class.equals(clazz))
                return Double.valueOf(sValue);
            else if (Character.TYPE.equals(clazz) || Character.class.equals(clazz)) {
                char charValue = 0;
                if (sValue.length() > 0) {
                    charValue = sValue.charAt(0);
                }
                if (Character.TYPE.equals(clazz))
                    return charValue;
                else
                    return charValue;
            } else if (clazz.equals(Locale.class)) {
                String[] components = sValue.split("_", 2);
                if (components.length == 2) {
                    return new Locale(components[0], components[1]);
                } else {
                    return new Locale(sValue);
                }
            } else if (Enum.class.isAssignableFrom(clazz)) {
                return Enum.valueOf(clazz, sValue);
            }
        }

        return value;
    }

}
