package com.zhongdao.jlr.util;

import java.lang.reflect.Field;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/** 
 * Created by anqiansong on 2016/5/27. 
 * 主题:[案例1]XJson,目前只支持数据类型,Array,Map,List 
 */  
public class XJson { //===============================JSON解析=====================================
    /**
    * get jsonobject 
    * @param String json 
    * @return  JOSNObject
    */
    public static JSONObject getJsonObject(String json){
        JSONObject jsonObject = null;        
        try {
            jsonObject = new JSONObject(json);
        } catch (JSONException e) {
            e.getCause();
            return null;
        }
        return jsonObject;
    }
    /**
    * get jsonarray
    * @param String json
    * @return  JOSNArray
    */
    public static JSONArray getJsonArray(String json){
        JSONArray jsonArray= null;        
        try {
            jsonArray = new JSONArray(json);
        } catch (JSONException e) {
            //LogUtil.e(TAG, "create jsonobject exception");
            e.printStackTrace();
        }
        return jsonArray;
    }
    /**
    * get String data
    * @param json  json data
    * @param key param
    * @return  data
    * @throws JSONException
    */
    public static  String getString(String json,String key){
        JSONObject jsonObject=getJsonObject(json);
        if(jsonObject!= null){
            try {
                return jsonObject.getString(key);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return "";
            }
        }else{
            return null;
        }            
    }
    /**
    * get String data
    * @param json  json data
    * @param key param
    * @return  data
    * @throws JSONException
    */
    public static int getInt(String json,String key){
        JSONObject jsonObject=getJsonObject(json);
        if(jsonObject!= null){
            try {
                return jsonObject.getInt(key);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else{
            return -1;
        }
        return 0;
            
    }
    /**
    * get Double data
    * @param json  json data
    * @param key param
    * @return  data
    * @throws JSONException
    */
    public static double getDouble(String json,String key){
        JSONObject jsonObject=getJsonObject(json);
        if(jsonObject!= null){
            try {
                return jsonObject.getDouble(key);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return 0d;
            }
        }else{
            return -1;
        }
    }
    
    /**
    *    <p>parent {@link Object getObject(String json,Class<?> c,String key)}</p>
     * @return 
    */
    public static  Object getObject(String json,Class<?> c){
        JSONObject jo=getJsonObject(json);
        if(jo==null){
            return null;
        }
        return getObject(jo,c);
    }
    /**
    * This Method use in jsonObject get current class with object :{"a":"x","b":"xx"}
    * @param jsonObject
    * @param key   query key,not null
    * @param c  class 
    * @return  object 
    * @throws Exception
    */
    public static  Object getObject(String json,Class<?> c,String key){
        JSONObject jo = null;
        if(key!=null){
            try {
                jo =  getJsonObject(json).getJSONObject(key);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(jo==null){
            return null;
        }        
        return getObject(jo,c);
    }
    /**
     * 解析JSONObject对象，返回Object 
     * @param jo
     * @param c
     * @return Object of class c
     */
    public static  Object getObject(JSONObject jo,Class<?> c){
        Object bean=null;
        try {
            bean = c.newInstance();
        } catch (InstantiationException e) {            
            e.printStackTrace();            
        } catch (IllegalAccessException e) {            
            e.printStackTrace();
        }
        Field[] fs = c.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];                        
            f.setAccessible(true);
            String type = f.getType().getSimpleName();//f.getGenericType();
            //LogUtil.print("type="+type.toString()+","+f.getType()+",name="+f.getName());
            String value = null;
            try{
                try{
                    value = jo.getString(f.getName());
                }catch (JSONException e) {
                    value=null;
                }
                if(type.equals(boolean.class.getSimpleName())){
                    f.setBoolean(bean,Boolean.valueOf(value));                
                }else if(type.equals(int.class.getSimpleName())){
                    f.setInt(bean,Integer.valueOf(value));                
                }else if(type.equals(double.class.getSimpleName())){
                    f.setDouble(bean, Double.valueOf(value));
                }else if(type.equals(long.class.getSimpleName())){
                    f.setLong(bean, Long.valueOf(value));
                }else if(type.equals(String.class.getSimpleName())){
                    f.set(bean,value);
                }else if(type.equals("List")){ 
                    String listClass=f.getGenericType().toString();
                    listClass=listClass.substring(listClass.lastIndexOf("<")+1, listClass.lastIndexOf(">"));
                    //LogUtil.print(listClass);
                    Class<?> listCls=null;
                    try {
                        listCls=Class.forName(listClass);
                    } catch (ClassNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    if(listCls!=null){
                        if(value==null){
                            f.set(bean, null);
                        }else{
                            f.set(bean, getList(value, listCls));
                        }                        
                    }
                }else{    
                    //f.set(bean,getBaseObject(value, f.getType()));
                    f.set(bean,getObject(getJsonObject(value), f.getType()));
                }
            }catch(NumberFormatException e){
                e.printStackTrace();
            }catch(IllegalAccessException e){
                e.printStackTrace();
            }catch(IllegalArgumentException e){
                e.printStackTrace();                
            }
        }
        return bean;
    }    
    /**
     * This method use in jsonObject get list object:{"b":[{"a":"x","b":"xx"},{"a":"x","b":"xx"}]}
     * @param key  list key,such as the "b",not null
     * @param objectKey  object key
     * @param c  object
     * @return   list
     * @throws Exception
     */
    public static  List<Object> getList(String json,String key ,Class<?> c){
        JSONObject jsonObject=getJsonObject(json);
        List<Object> list = null;
        if(jsonObject!=null && key!=null){
            try {
                list=getList(jsonObject.getJSONArray(key).toString(), c);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return list;
    }
        
    /**
     * 获取List<E>的基本数据，This method use in jsonObject get list object:[{"a":"x","b":"xx"},{"a":"x","b":"xx"}]
     * @param json
     * @param c
     * @return List<Object>,object of class c
     */
    public static  List<Object> getList(String json,Class<?> c){
        List<Object> list = null;
        JSONArray jsonArray = null;
        try {
            jsonArray = new JSONArray(json);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        if(!jsonArray.isNull(0)){
            list = new ArrayList<Object>();
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsObject = null;
                try {
                    jsObject = jsonArray.getJSONObject(i);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Object object = getObject(getJsonObject(jsObject.toString()),c);
                list.add(object);
            }
        }
        return list;
    }
    //=========================================JSON生成=================================
    /***
     * create json object data:{"a":"x","b":"xx"}
     */
    public static String jsonObject_encodeToString(Object bean){
        return jsonObject_encode(bean).toString();
    }
    @SuppressWarnings("unchecked")
    public static JSONObject jsonObject_encode(Object bean){        
        JSONObject jsonObject = new JSONObject();
        Field[] fs = bean.getClass().getDeclaredFields();        
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true);
            //LogUtil.print("object type="+f.getType().getSimpleName()+",name="+f.getName());
            try {            
                if(f.getType().getSimpleName().equals("List")){
                    
                    if(f.get(bean)!=null){
                        jsonObject.put(f.getName(),jsonArray_encode((List<Object>)f.get(bean)));
                    }else{
                        jsonObject.put(f.getName(),"");
                    }
                }else if(f.getType().getSimpleName().equals(String.class.getSimpleName()) ||
                         f.getType().getSimpleName().equals(boolean.class.getSimpleName()) ||
                         f.getType().getSimpleName().equals(int.class.getSimpleName())     ||
                         f.getType().getSimpleName().equals(long.class.getSimpleName())      ||
                         f.getType().getSimpleName().equals(double.class.getSimpleName()) ||
                         f.getType().getSimpleName().equals(float.class.getSimpleName())     ||
                         f.getType().getSimpleName().equals(double.class.getSimpleName())){
                    jsonObject.put(f.getName(),f.get(bean));
                }else{    
                    Object object=null;
                    try {
                        object=f.getType().newInstance();                        
                    } catch (InstantiationException e) {                        
                        e.printStackTrace();
                    }
                    object=f.get(bean);
                    jsonObject.put(f.getName(),jsonObject_encode(object));
                }
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return jsonObject;
    }    
    /***
     * create json array data:[{"a":"x","b":"xx"},{"a":"x","b":"xx"}]
     */
    public static String jsonArray_encodeToString(List<Object> list){
        return jsonArray_encode(list).toString();
    }    
    @SuppressWarnings("unchecked")
    private static JSONArray jsonArray_encode(List<Object> list){        
        JSONArray jsonArray=new JSONArray();
        for(int n=0;n<list.size();n++){
            JSONObject jsonObject = new JSONObject();
            Object bean=list.get(n);
            Field[] fs = bean.getClass().getDeclaredFields();
            for (int i = 0; i < fs.length; i++) {
                Field f = fs[i];
                f.setAccessible(true);
                //LogUtil.print("array type="+f.getType().getSimpleName()+",name="+f.getName());
                try {        
                    if(f.getType().getSimpleName().equals("List")){
                        if(f.get(bean)!=null){
                            jsonObject.put(f.getName(),jsonArray_encode((List<Object>)f.get(bean)));
                        }else{
                            jsonObject.put(f.getName(),"");
                        }
                    }else if(f.getType().getSimpleName().equals(String.class.getSimpleName()) ||
                             f.getType().getSimpleName().equals(boolean.class.getSimpleName()) ||
                             f.getType().getSimpleName().equals(int.class.getSimpleName())     ||
                             f.getType().getSimpleName().equals(long.class.getSimpleName())      ||
                             f.getType().getSimpleName().equals(double.class.getSimpleName()) ||
                             f.getType().getSimpleName().equals(float.class.getSimpleName())     ||
                             f.getType().getSimpleName().equals(double.class.getSimpleName())){
                        jsonObject.put(f.getName(),f.get(bean));
                    }else{
                        Object object=null;
                        try {
                            object=f.getType().newInstance();                        
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        }catch (Exception e) {
                           // e.printStackTrace();
                        }
                        object=f.get(bean);
                        jsonObject.put(f.getName(),jsonObject_encode(object));
                    }                    
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                 catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            try {
                jsonArray.put(n, jsonObject);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return jsonArray;
    }
    /***
     * create String array data:[{"0":"str0"},{"1":"str1"}]
     */
    public static String stringArray_encode(List<String> list){        
        JSONArray jsonArray=new JSONArray();
        for(int n=0;n<list.size();n++){            
            String bean=list.get(n);            
            try {
                jsonArray.put(n, bean);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return jsonArray.toString();
    }
    //==========================获取对象key and value=============================
    /**
     * return the object's field value
     * @param classObject
     * @param c
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static  String getObjectValue(Object Object,Class<?> c){
        StringBuffer sb = new StringBuffer();
        Field[] fs = c.getDeclaredFields();        
        for (int i = 0; i < fs.length; i++) {        
            String s="";
            Field fd=fs[i];
            try {
                fd.setAccessible(true);
                s = fd.getName()+"="+fd.get(Object);
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            sb.append(s).append(";");
        }
        sb.append("\n");
        return sb.toString();
    }    
}
