package com.wisedu.coeus.util.json;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.JSONSerializerMap;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;

public class JSONObject implements Map<String, Object> {
    private com.alibaba.fastjson.JSONObject json;
    private com.alibaba.fastjson.JSONArray jsonArray;

    private static final JSONSerializerMap mapping;
    static {
        mapping = new JSONSerializerMap();
        mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd"));
    }

    private static final SerializerFeature[] features = { SerializerFeature.WriteMapNullValue, // 输出空置字段
            SerializerFeature.WriteNullListAsEmpty, // list字段如果为null，输出为[]，而不是null
            SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null，输出为0，而不是null
            SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null，输出为false，而不是null
            SerializerFeature.WriteNullStringAsEmpty, // 字符类型字段如果为null，输出为""，而不是null
            SerializerFeature.DisableCircularReferenceDetect, // 禁用循环引用
    };

    public JSONObject() {
        this.jsonArray = null;
        this.json = new com.alibaba.fastjson.JSONObject();
    }

    public JSONObject(Object object) {
        this.jsonArray = null;
        this.json = null;
        if (object instanceof com.alibaba.fastjson.JSONObject) {
            this.json = (com.alibaba.fastjson.JSONObject) object;
        } else if (object instanceof String) {
            this.json = JSON.parseObject(object.toString());
        } else {
            Object o = JSON.toJSON(object);

            if (o instanceof com.alibaba.fastjson.JSONObject) {
                this.json = (com.alibaba.fastjson.JSONObject) o;
            } else if (o instanceof com.alibaba.fastjson.JSONArray) {
                this.jsonArray = (com.alibaba.fastjson.JSONArray) o;
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T parseObject(String object, Class clazz) {
        Pattern pattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}");
        Matcher matcher = pattern.matcher(object);
        if (matcher.find()) {
            return (T) JSON.parseObject(object, (Type) clazz, Feature.AllowISO8601DateFormat);
        } else {
            return (T) JSON.parseObject(object, (Type) clazz);
        }

    }

    public static JSONObject parseObject(String object) {
        return new JSONObject(object);
    }

    public static JSONObject fromObject(java.lang.Object object) {
        return new JSONObject(object);
    }

    public static java.lang.Object toBean(JSONObject jsonObject, java.lang.Class beanClass) {
        return com.alibaba.fastjson.JSON.toJavaObject(jsonObject.json, beanClass);
    }

    public static String toJSONString(Object object) {
        return com.alibaba.fastjson.JSON.toJSONString(object, mapping, features);
    }

    public JSONObject getJSONObject(String key) {
        return new JSONObject(this.json.get(key));
    }

    public JSONArray getJSONArray(String key) {
        com.alibaba.fastjson.JSONArray array = this.json.getJSONArray(key);
        if (array == null || array.size() == 0) {
            return null;
        }
        return new JSONArray(array);
    }

    public List<String> getStringList(String key) {
        JSONArray arr = this.getJSONArray(key);
        if (arr == null || arr.size() == 0) {
            return Collections.emptyList();
        }
        Object[] objArr = arr.toArray();
        List<String> list = new ArrayList<String>();
        for (int i = 0, size = objArr.length; i < size; i++) {
            list.add((String) objArr[i]);
        }
        return list;
    }

    public static JSONArray toJSONArray(String object) {
        com.alibaba.fastjson.JSONArray array = JSON.parseArray(object);
        if (array == null || array.size() == 0) {
            return null;
        }
        return new JSONArray(array);
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this.json, mapping, features);
    }

    @Override
    public int size() {
        if (this.json == null) {
            return 0;
        }
        return this.json.size();
    }

    @Override
    public boolean isEmpty() {
        if (this.json == null) {
            return true;
        }
        return this.json.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        if (this.json == null) {
            return false;
        }
        return this.json.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        if (this.json == null) {
            return false;
        }
        return this.json.containsValue(value);
    }

    @Override
    public Object get(Object key) {
        if (this.json == null) {
            return null;
        }
        return this.json.get(key);
    }

    @Override
    public Object put(String key, Object value) {
        if (this.json == null) {
            return null;
        }
        return this.json.put(key, value);
    }

    @Override
    public Object remove(Object key) {
        if (this.json == null) {
            return null;
        }
        return this.json.remove(key);
    }

    @Override
    public void putAll(Map map) {
        if (this.json == null) {
            return;
        }
        this.json.putAll(map);
    }

    @Override
    public void clear() {
        if (this.json == null) {
            return;
        }
        this.json.clear();
    }

    @Override
    public Set keySet() {
        if (this.json == null) {
            return null;
        }
        return this.json.keySet();
    }

    @Override
    public Collection values() {
        if (this.json == null) {
            return null;
        }
        return this.json.values();
    }

    @Override
    public Set entrySet() {
        if (this.json == null) {
            return null;
        }
        return this.json.entrySet();
    }

    public Iterator keys() {
        if (this.json == null) {
            return null;
        }
        return this.json.keySet().iterator();
    }

    public String getString(String key) {
        if (this.json == null) {
            return null;
        }
        return this.json.getString(key);
    }

    public Float getFloat(String key) {
        if (this.json == null) {
            return null;
        }
        return this.json.getFloat(key);
    }

    public int getInt(String key) {
        if (this.json == null) {
            return 0;
        }
        return this.json.getIntValue(key);
    }
    
     public long getLong(String key) {
        if (this.json == null) {
            return 0l;
        }
        return this.json.getLongValue(key);
    }
}
