package cn.ysk.cashier.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;

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

/**
 * @author Stone
 * @version V1.0.0
 * @date 2020/2/12
 */
public class JSONUtil {


    /**
     * 将对象转为JSON字符串
     *
     * @param obj        被转的对象
     * @param dateFormat 日期格式，当传null或空串时，则被格式化为时间戳，否则返回指定的格式。例子：yyyy-MM-dd HH:mm:ss（不合法的日期格式会格式化出错）
     * @param ignoreNull 是否忽略null字段。true时，且当字段的值是null，则不输出该字段
     * @param noRef      是否不转换成ref。例如false，当字段间是相同的引用之时，则将出现$ref之类的符号替代冗余的值
     * @param pretty     是否格式化JSON字符串以便有更好的可读性
     * @return JSON字符串，出异常时抛出
     */
    public static String toJSONString0(Object obj,
                                       String dateFormat,
                                       boolean ignoreNull,
                                       boolean noRef,
                                       boolean pretty) {
        try {
            List<SerializerFeature> featureList = new ArrayList<>();

            // 当传null时，则返回默认的时间戳，否则则返回指定的格式
            if (dateFormat != null && dateFormat.length() > 0) {
                featureList.add(SerializerFeature.WriteDateUseDateFormat);
            }
            if (!ignoreNull) {
                // 当字段的值是null时，依然出现这个字段，即不忽略
                featureList.add(SerializerFeature.WriteMapNullValue);
            }
            if (noRef) {
                featureList.add(SerializerFeature.DisableCircularReferenceDetect);
            }
            if (pretty) {
                featureList.add(SerializerFeature.PrettyFormat);
            }

            SerializerFeature[] featureArr = featureList.toArray(new SerializerFeature[featureList.size()]);
            return JSONObject.toJSONString(obj, SerializeConfig.globalInstance, null, dateFormat,
                    JSON.DEFAULT_GENERATE_FEATURE, featureArr);
        } catch (Exception e) {
            throw new RuntimeException("Convert object to JSON string, error[" + obj + "]", e);
        }
    }

    /**
     * 将对象转为JSON字符串。
     * 日期转为特别的格式，不忽略null值的字段，不格式化JSON字符串
     *
     * @param obj 被转换的对象
     * @return JSON字符串，发送异常时抛出
     */
    public static String toJSONString(Object obj) {
        return toJSONString0(obj, "yyyy-MM-dd HH:mm:ss", false, true, false);
    }


    /**
     * 字符串转为某个类
     * （日期字段不管是时间戳形式还是yyyy-MM-dd HH:mm:ss的形式都能成功转换）
     * （假设json字符串多了某个字段，可能是新加上去的，T类没有，转换成T对象的时候，不会抛出异常）
     *
     * @param jsonStr 传入的JSON字串
     * @param clazz   转为什么类型
     * @return 返回转换结果。当传入的JSON字串是数组形式时，会抛出异常
     * @author Stone
     */
    public static <T> T parseJSONStr2T(String jsonStr, Class<T> clazz) {
        try {
            return JSONObject.parseObject(jsonStr, clazz);
        } catch (Exception e) {
            throw new RuntimeException("Invalid jsonStr,parse error:" + jsonStr, e);
        }
    }

    public static void main(String[] args) {
        String sss = "{\"bizData\":{\"amount\":1,\"currency\":\"cny\",\"ifCode\":\"sxfpay\",\"mchOrderNo\":\"CZ1715744291232\",\"mercNo\":\"B240510702030\",\"note\":\"等待用户付款\",\"payOrderId\":\"O1790587460614225921\",\"payType\":\"WECHAT\",\"settlementType\":\"D1\",\"state\":\"TRADE_AWAIT\",\"storeId\":\"S2405103298\",\"subject\":\"测试支付\",\"tradeFee\":0},\"code\":\"000000\",\"msg\":\"请求成功\",\"sign\":\"40710a3c293eeac3c7f4a1b0696a2bf6\",\"signType\":\"MD5\",\"timestamp\":\"20240515113813\"}";
//        TypeReference<PublicResp<MainScanResp>> typeRef = new TypeReference<PublicResp<MainScanResp>>(){};
//        PublicResp<MainScanResp> response = JSON.parseObject(sss, typeRef);
        System.out.println("pm");
    }
}


