package com.ag.util;

import cn.hutool.core.util.XmlUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;

import java.util.Iterator;

/**
 * Created by yangxh on 2019/9/18.
 */
public class XMLUtil extends XML {


    public static String toXml(Object object) throws JSONException {
        return toXml(object, null);
    }

    public static String toXml(Object object, String tagName) throws JSONException {
        if(null == object) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        JSONArray ja;
        JSONObject jo;
        String key;
        Iterator<String> keys;
        String string;
        Object value;

        if (object instanceof JSONObject) {

            // Emit <tagName>
            if (tagName != null) {
                sb.append('<');
                sb.append(tagName);
            }

            // Loop thru the keys.
            jo = (JSONObject) object;
            Iterator<String> eles = jo.keySet().iterator();
            while (eles.hasNext()) {
                key = eles.next();
                value = jo.get(key);
                if (key.startsWith("@")){
                    sb.append(" ").append(key.substring(1)).append("=").append("\"").append(value).append("\"");
                    eles.remove();
                }
            }
            if (tagName != null) {
                sb.append('>');
            }

            keys = jo.keySet().iterator();
            while (keys.hasNext()) {
                key = keys.next();
                value = jo.get(key);
                if (value == null) {
                    value = "";
                } else if (value.getClass().isArray()) {
                    value = new JSONArray(value);
                }
                string = value instanceof String ? (String) value : null;

                // Emit content in body
                if ("content".equals(key)) {
                    if (value instanceof JSONArray) {
                        ja = (JSONArray) value;
                        int i = 0;
                        for (Object val : ja) {
                            if (i > 0) {
                                sb.append('\n');
                            }
                            sb.append(XmlUtil.escape(val.toString()));
                            i++;
                        }
                    } else {
                        sb.append(XmlUtil.escape(value.toString()));
                    }

                    // Emit an array of similar keys

                } else if (value instanceof JSONArray) {
                    ja = (JSONArray) value;
                    for (Object val : ja) {
                        if (val instanceof JSONArray) {
                            sb.append('<');
                            sb.append(key);
                            sb.append('>');
                            sb.append(toXml(val));
                            sb.append("</");
                            sb.append(key);
                            sb.append('>');
                        } else {
                            sb.append(toXml(val, key));
                        }
                    }
                } else if ("".equals(value)) {
                    sb.append('<');
                    sb.append(key);
                    sb.append("/>");

                    // Emit a new tag <k>

                } else {
                    sb.append(toXml(value, key));
                }
            }
            if (tagName != null) {

                // Emit the </tagname> close tag
                sb.append("</");
                sb.append(tagName);
                sb.append('>');
            }
            return sb.toString();

        }

        if (object != null) {
            if (object.getClass().isArray()) {
                object = new JSONArray(object);
            }

            if (object instanceof JSONArray) {
                ja = (JSONArray) object;
                for (Object val : ja) {
                    // XML does not have good support for arrays. If an array
                    // appears in a place where XML is lacking, synthesize an
                    // <array> element.
                    sb.append(toXml(val, tagName == null ? "array" : tagName));
                }
                return sb.toString();
            }
        }

        string = (object == null || "null".equals(object.toString())) ? "" : XmlUtil.escape(object.toString());
        return (tagName == null) ? "\"" + string + "\"" : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName + ">" + string + "</" + tagName + ">";

    }
}
