package com.uas.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser.Feature;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;
import java.util.*;

/**
 * <h1>jackson</h1><br>
 * 建议反序列化采用和序列化同一util，不要jackson和flexjson混着用，否则消耗会加大很多
 * 
 * @author yingp
 * 
 */
public class JacksonUtil {
	private static com.fasterxml.jackson.databind.ObjectMapper objectMapper;

	@SuppressWarnings("unchecked")
	public static <T> List<T> fromJsonArray(String json) {
		ObjectMapper mapper = getObjectMapper();
		try {
			return mapper.readValue(json, List.class);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 字段必须是有引号的，形如{"a":"1","b":2}<br>
	 * 如果格式是{a:"1",b:2}是无法解析的
	 * 
	 * @param json
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <K, V> HashMap<K, V> fromJson(String json) {
		ObjectMapper mapper = getObjectMapper();
		try {
			return mapper.readValue(json, HashMap.class);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String toJson(Map<?, ?> map) {
		ObjectMapper mapper = getObjectMapper();
		try {
			return mapper.writeValueAsString(map);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String toJsonArray(Collection<?> collection) {
		ObjectMapper mapper = getObjectMapper();
		try {
			return mapper.writeValueAsString(collection);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static ObjectMapper getObjectMapper() {
		ObjectMapper mapper = new ObjectMapper();
		mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
		mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
		return mapper;
	}

	/**
	 * 使用 Map按key进行排序
	 * @param map
	 * @return
	 */
	public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
		if (map == null || map.isEmpty()) {
			return null;
		}

		Map<String, Object> sortMap = new TreeMap<String, Object>(
				new MapKeyComparator());

		sortMap.putAll(map);

		return sortMap;
	}

	public static String toSortJson(Map<String, Object> map) {
		map = sortMapByKey(map);
		ObjectMapper mapper = getObjectMapper();
		try {
			return mapper.writeValueAsString(map);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 把JSON文本parse为JavaBean.
	 */
	public static <T> T fromJson(String text, Class<T> clazz) {
		if (objectMapper == null) {
			objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
		}

		try {
			return objectMapper.readValue(text, clazz);
		} catch (IOException e) {
			throw new RuntimeException("转换Java对象失败", e);
		}
	}

	/**
	 * 把JSON文本parse为JavaBean.
	 */
	public static <T> T fromJson(Map<?,?> map, Class<T> clazz) {
		String text = toJson(map);
		if (objectMapper == null) {
			objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
		}

		try {
			return objectMapper.readValue(text, clazz);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("转换Java对象失败", e);
		}
	}

	/**
	 * 将JavaBean序列化为JSON文本.
	 */
	public static String toJson(Object object) {
		if (objectMapper == null) {
			objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
		}

		try {
			return objectMapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			throw new RuntimeException("序列化成Json失败", e);
		}
	}
}
