package com.tuoheng.common.core.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Map;

public class JacksonUtil {

    private final static Logger LOGGER = LoggerFactory.getLogger(JacksonUtil.class);

    private final static ObjectMapper objectMapper = new ObjectMapper();

    private final static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private JacksonUtil(){}

    static {
        //序列化的时候序列对象的所有属性
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        //反序列化的时候如果多了其他属性,不抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //如果是空对象的时候,不抛异常
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        //取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.setDateFormat(dateformat);
    }

    /**
     * 转换为 JSON 字符串
     *
     * @param obj
     * @return
     */
    public static <T> String obj2json(T obj) {
        if(obj != null){
            try {
                return obj instanceof String ? (String)obj : objectMapper.writeValueAsString(obj);
            } catch (Exception e) {
                LOGGER.error("对象转字符串异常: {}", e);
            }
        }
        return null;
    }

    /**
     * 漂亮的转换为 JSON 字符串
     *
     * @param obj
     * @return
     */
    public static <T> String obj2StringPretty(T obj) {
        if(obj != null){
            try {
                return obj instanceof String ? (String)obj :  objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            } catch (Exception e) {
                LOGGER.error("对象转字符串异常: {}", e);
            }
        }
        return null;
    }

    /**
     * 转换为 JavaBean
     *
     * @param str
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T json2pojo(String str, Class<T> clazz) {
        if(StringUtils.hasLength(str) && clazz != null){
            try {
                return clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
            } catch (Exception e) {
                LOGGER.error("字符串转对象异常: {}", e);
            }
        }
        return null;
    }

    /**
     * 将 Map 转换为 JavaBean
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T map2pojo(Map map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }

    /**
     * 将 JSON 对象转换为 JavaBean
     *
     * @param obj
     * @param clazz
     * @return
     */
    public static <T> T obj2pojo(Object obj, Class<T> clazz) {
        return objectMapper.convertValue(obj, clazz);
    }

    /**
     * 将指定节点的 JSON 数据转换为 JavaBean
     *
     * @param str
     * @param treeNode
     * @param clazz
     * @return
     */
    public static <T> T json2pojoByTree(String str, String treeNode, Class<T> clazz) {
        if(StringUtils.hasLength(str) && StringUtils.hasLength(str) && clazz == null){
            try {
                JsonNode jsonNode = objectMapper.readTree(str);
                JsonNode data = jsonNode.findPath(treeNode);
                return json2pojo(data.toString(), clazz);
            } catch (Exception e) {
                LOGGER.error("字符串按节点转对象异常: {}", e);
            }
        }
        return null;
    }
}