package org.springblade.openinterface.dianxin.util;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

/**
 * @author lidexi
 * @date 2021/6/23 18:59
 */

public class JsonString {

	/**
	 * 对象转换为Json字符串，输出格式 {"参数": "值"}
	 *
	 * @param o 待转换对象
	 * @return 转换后的Json串
	 */
	public static String asJsonString(Object o) {
		StringBuilder json = new StringBuilder();
		asJson(json, o, 0);
		return json.toString();
	}

	private static void asJson(StringBuilder json, Object o, int level) {
		if (o == null) {
			json.append("null");
		} else if (o instanceof String || o instanceof Boolean) {
			json.append('"').append(o).append('"');
			return;
		} else if (o instanceof Integer || o instanceof Double || o instanceof Long || o instanceof Float
			|| o instanceof Short || o instanceof Byte || o instanceof BigDecimal) {
			json.append(o);
		} else if (o instanceof Date) {
			json.append('"').append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(o)).append('"');
		} else if (o instanceof Array) {
			jsonArray(json, (Object[]) o, level);
		} else if (o instanceof Map) {
			jsonMap(json, (Map) o, level);
		} else if (o instanceof Collection) {
			jsonCollection(json, (Collection) o, level);
		} else {
			jsonObject(json, o, level);
		}
	}

	private static void jsonCollection(StringBuilder json, Collection co, int level) {
		json.append('[');
		boolean isFirst = true;
		for (Object o : co) {
			if (isFirst) {
				isFirst = false;
			} else {
				json.append(',');
			}
			asJson(json, o, level + 1);
		}
		json.append(']');
	}

	private static void jsonArray(StringBuilder json, Object[] co, int level) {
		json.append('[');
		boolean isFirst = true;
		for (Object o : co) {
			if (isFirst) {
				isFirst = false;
			} else {
				json.append(',');
			}
			asJson(json, o, level + 1);
		}
		json.append(']');
	}

	private static void jsonMap(StringBuilder json, Map map, int level) {
		json.append('{');
		boolean isFirst = true;
		for (Object o : map.entrySet()) {
			Map.Entry e = (Map.Entry) o;
			if (e.getValue() == null)
				continue;
			if (isFirst) {
				isFirst = false;
			} else {
				json.append(',');
			}
			json.append('"').append(e.getKey()).append("\" : ");
			asJson(json, e.getValue(), level + 1);
		}
		json.append('}');
	}

	private static String firstLower(String str) {
		char[] ca = str.toCharArray();
		if (ca[0] < 91)
			ca[0] += 32;
		return new String(ca);
	}

	private static void jsonObject(StringBuilder json, Object o, int level) {
		json.append('{');
		boolean isFirst = true;
		Method[] methods = o.getClass().getDeclaredMethods();
		for (Method m : methods) {
			String name = m.getName();
			if (!name.startsWith("get"))
				continue;
			Object value = null;
			try {
				value = m.invoke(o, null);
			} catch (Exception e) {
				e.printStackTrace();
				// log.warn(" fail to get value:",o.getClass(),m.getName(), e);
			}
			if (value == null)
				continue;
			name = firstLower(name.substring(3));

			if (isFirst) {
				isFirst = false;
			} else {
				json.append(',');
			}
			json.append('"').append(name).append("\" : ");
			asJson(json, value, level + 1);
		}
		json.append('}');
	}

}
