//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.util.ajax;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.eclipse.jetty.util.ajax.JSON.Output;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
 * Converts POJOs to JSON and vice versa.
 * The key difference:
 *  - returns the actual object from Convertor.fromJSON (JSONObjectConverter returns a Map)
 *  - the getters/setters are resolved at initialization (JSONObjectConverter resolves it at runtime)
 *  - correctly sets the number fields
 * 
 */
public class JSONPojoConvertor implements JSON.Convertor
{
    private static final Logger LOG = Log.getLogger(JSONPojoConvertor.class);
    public static final Object[] GETTER_ARG = new Object[]{}, NULL_ARG = new Object[]{null};
    private static final Map<Class<?>, NumberType> __numberTypes = new HashMap<Class<?>, NumberType>();
    
    public static NumberType getNumberType(Class<?> clazz)
    {
        return __numberTypes.get(clazz);
    }
    
    protected boolean _fromJSON;
    protected Class<?> _pojoClass;
    protected Map<String,Method> _getters = new HashMap<String,Method>();
    protected Map<String,Setter> _setters = new HashMap<String,Setter>();
    protected Set<String> _excluded;

    /**
     * @param pojoClass The class to convert
     */
    public JSONPojoConvertor(Class<?> pojoClass)
    {
        this(pojoClass, (Set<String>)null, true);
    }

    /**
     * @param pojoClass The class to convert
     * @param excluded The fields to exclude
     */
    public JSONPojoConvertor(Class<?> pojoClass, String[] excluded)
    {
        this(pojoClass, new HashSet<String>(Arrays.asList(excluded)), true);
    }

    /**
     * @param pojoClass The class to convert
     * @param excluded The fields to exclude
     */
    public JSONPojoConvertor(Class<?> pojoClass, Set<String> excluded)
    {
        this(pojoClass, excluded, true);
    }

    /**
     * @param pojoClass The class to convert
     * @param excluded The fields to exclude
     * @param fromJSON If true, add a class field to the JSON
     */
    public JSONPojoConvertor(Class<?> pojoClass, Set<String> excluded, boolean fromJSON)
    {
        _pojoClass = pojoClass;
        _excluded = excluded;
        _fromJSON = fromJSON;
        init();
    }    

    /**
     * @param pojoClass The class to convert
     * @param fromJSON If true, add a class field to the JSON
     */
    public JSONPojoConvertor(Class<?> pojoClass, boolean fromJSON)
    {
        this(pojoClass, (Set<String>)null, fromJSON);
    }
    
    /* ------------------------------------------------------------ */
    protected void init()
    {
        Method[] methods = _pojoClass.getMethods();
        for (int i=0;i<methods.length;i++)
        {
            Method m=methods[i];
            if (!Modifier.isStatic(m.getModifiers()) && m.getDeclaringClass()!=Object.class)
            {
                String name=m.getName();
                switch(m.getParameterCount())
                {
                    case 0:
                        
                        if(m.getReturnType()!=null)
                        {
                            if (name.startsWith("is") && name.length()>2)
                                name=name.substring(2,3).toLowerCase(Locale.ENGLISH)+name.substring(3);
                            else if (name.startsWith("get") && name.length()>3)
                                name=name.substring(3,4).toLowerCase(Locale.ENGLISH)+name.substring(4);
                            else 
                                break;
                            if(includeField(name, m))
                                addGetter(name, m);
                        }
                        break;
                    case 1:
                        if (name.startsWith("set") && name.length()>3)
                        {
                            name=name.substring(3,4).toLowerCase(Locale.ENGLISH)+name.substring(4);
                            if(includeField(name, m))
                                addSetter(name, m);
                        }
                        break;                
                }
            }
        }
    }
    
    /* ------------------------------------------------------------ */
    protected void addGetter(String name, Method method)
    {
        _getters.put(name, method);
    }
    
    /* ------------------------------------------------------------ */
    protected void addSetter(String name, Method method)
    {
        _setters.put(name, new Setter(name, method));
    }
    
    /* ------------------------------------------------------------ */
    protected Setter getSetter(String name)
    {
        return _setters.get(name);
    }

    /* ------------------------------------------------------------ */
    protected boolean includeField(String name, Method m)
    {
        return _excluded==null || !_excluded.contains(name);
    }
    
    /* ------------------------------------------------------------ */
    protected int getExcludedCount()
    {
        return _excluded==null ? 0 : _excluded.size();
    }

    /* ------------------------------------------------------------ */
    public Object fromJSON(Map object)
    {        
        Object obj = null;
        try
        {
            obj = _pojoClass.newInstance();
        }
        catch(Exception e)
        {
            // TODO return Map instead?
            throw new RuntimeException(e);
        }
        
        setProps(obj, object);
        return obj;
    }
    
    /* ------------------------------------------------------------ */
    public int setProps(Object obj, Map<?,?> props)
    {
        int count = 0;
        for(Iterator<?> iterator = props.entrySet().iterator(); iterator.hasNext();)
        {
            Map.Entry<?, ?> entry = (Map.Entry<?,?>) iterator.next();
            Setter setter = getSetter((String)entry.getKey());
            if(setter!=null)
            {
                try
                {
                    setter.invoke(obj, entry.getValue());                    
                    count++;
                }
                catch(Exception e)
                {
                    // TODO throw exception?
                    LOG.warn(_pojoClass.getName()+"#"+setter.getPropertyName()+" not set from "+
                            (entry.getValue().getClass().getName())+"="+entry.getValue().toString());
                    log(e);
                }
            }
        }
        return count;
    }

    /* ------------------------------------------------------------ */
    public void toJSON(Object obj, Output out)
    {
        if(_fromJSON)
            out.addClass(_pojoClass);
        for(Map.Entry<String,Method> entry : _getters.entrySet())
        {            
            try
            {
                out.add(entry.getKey(), entry.getValue().invoke(obj, GETTER_ARG));                    
            }
            catch(Exception e)
            {
                // TODO throw exception?
                LOG.warn("{} property '{}' excluded. (errors)", _pojoClass.getName(), 
                        entry.getKey());
                log(e);
            }
        }        
    }
    
    /* ------------------------------------------------------------ */
    protected void log(Throwable t)
    {
        LOG.ignore(t);
    }

    /* ------------------------------------------------------------ */
    public static class Setter
    {
        protected String _propertyName;
        protected Method _setter;
        protected NumberType _numberType;
        protected Class<?> _type;
        protected Class<?> _componentType;
        
        public Setter(String propertyName, Method method)
        {
            _propertyName = propertyName;
            _setter = method;
            _type = method.getParameterTypes()[0];
            _numberType = __numberTypes.get(_type);
            if(_numberType==null && _type.isArray())
            {
                _componentType = _type.getComponentType();
                _numberType = __numberTypes.get(_componentType);
            }
        }
        
        public String getPropertyName()
        {
            return _propertyName;
        }
        
        public Method getMethod()
        {
            return _setter;
        }
        
        public NumberType getNumberType()
        {
            return _numberType;
        }
        
        public Class<?> getType()
        {
            return _type;
        }
        
        public Class<?> getComponentType()
        {
            return _componentType;
        }
        
        public boolean isPropertyNumber()
        {
            return _numberType!=null;
        }
        
        public void invoke(Object obj, Object value) throws IllegalArgumentException, 
        IllegalAccessException, InvocationTargetException
        {
            if(value==null)
                _setter.invoke(obj, NULL_ARG);
            else
                invokeObject(obj, value);
        }
        
        protected void invokeObject(Object obj, Object value) throws IllegalArgumentException, 
            IllegalAccessException, InvocationTargetException
        {
            
            if (_type.isEnum())
            {
                if (value instanceof Enum)
                    _setter.invoke(obj, new Object[]{value});
                else
                    _setter.invoke(obj, new Object[]{Enum.valueOf((Class<? extends Enum>)_type,value.toString())});
            }
            else if(_numberType!=null && value instanceof Number)
            {
                _setter.invoke(obj, new Object[]{_numberType.getActualValue((Number)value)});
            }
            else if (Character.TYPE.equals(_type) || Character.class.equals(_type))
            {
                _setter.invoke(obj, new Object[]{String.valueOf(value).charAt(0)});
            }
            else if(_componentType!=null && value.getClass().isArray())
            {
                if(_numberType==null)
                {
                    int len = Array.getLength(value);
                    Object array = Array.newInstance(_componentType, len);
                    try
                    {
                        System.arraycopy(value, 0, array, 0, len);
                    }
                    catch(Exception e)
                    {                        
                        // unusual array with multiple types
                        LOG.ignore(e);
                        _setter.invoke(obj, new Object[]{value});
                        return;
                    }                    
                    _setter.invoke(obj, new Object[]{array});
                }
                else
                {
                    Object[] old = (Object[])value;
                    Object array = Array.newInstance(_componentType, old.length);
                    try
                    {
                        for(int i=0; i<old.length; i++)
                            Array.set(array, i, _numberType.getActualValue((Number)old[i]));
                    }
                    catch(Exception e)
                    {                        
                        // unusual array with multiple types
                        LOG.ignore(e);
                        _setter.invoke(obj, new Object[]{value});
                        return;
                    }
                    _setter.invoke(obj, new Object[]{array});
                }
            }
            else
                _setter.invoke(obj, new Object[]{value});
        }
    }
    
    public interface NumberType
    {        
        public Object getActualValue(Number number);     
    }
    
    public static final NumberType SHORT = new NumberType()
    {
        public Object getActualValue(Number number)
        {            
            return new Short(number.shortValue());
        } 
    };

    public static final NumberType INTEGER = new NumberType()
    {
        public Object getActualValue(Number number)
        {            
            return new Integer(number.intValue());
        }
    };
    
    public static final NumberType FLOAT = new NumberType()
    {
        public Object getActualValue(Number number)
        {            
            return new Float(number.floatValue());
        }      
    };

    public static final NumberType LONG = new NumberType()
    {
        public Object getActualValue(Number number)
        {            
            return number instanceof Long ? number : new Long(number.longValue());
        }     
    };

    public static final NumberType DOUBLE = new NumberType()
    {
        public Object getActualValue(Number number)
        {            
            return number instanceof Double ? number : new Double(number.doubleValue());
        }       
    };

    static
    {
        __numberTypes.put(Short.class, SHORT);
        __numberTypes.put(Short.TYPE, SHORT);
        __numberTypes.put(Integer.class, INTEGER);
        __numberTypes.put(Integer.TYPE, INTEGER);
        __numberTypes.put(Long.class, LONG);
        __numberTypes.put(Long.TYPE, LONG);
        __numberTypes.put(Float.class, FLOAT);
        __numberTypes.put(Float.TYPE, FLOAT);
        __numberTypes.put(Double.class, DOUBLE);
        __numberTypes.put(Double.TYPE, DOUBLE);
    }
}
