package ink.wgink.util.xml;

import ink.wgink.exceptions.base.SystemException;
import ink.wgink.util.ReflectUtil;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: XMLUtil
 * @Description: XML工具类
 * @Author: wanggeng
 * @Date: 2021/4/28 9:44 上午
 * @Version: 1.0
 */
public class XMLUtil {

    /**
     * XML转简单bean，bean属性类型为字符串
     *
     * @param xml
     * @param clazz
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T xml2SampleBean(String xml, Class<T> clazz) throws Exception {
        if (StringUtils.isBlank(xml)) {
            return null;
        }
        Field[] fields = clazz.getDeclaredFields();
        Map<String, String[]> getSetMethodMap = ReflectUtil.fieldGetSetMethod(fields);
        if (getSetMethodMap == null) {
            return null;
        }
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
        Element rootElement = document.getRootElement();
        List<Element> elements = rootElement.elements();
        if (elements.isEmpty()) {
            return null;
        }
        T t = clazz.newInstance();
        for (Element element : elements) {
            String elementName = element.getName();
            String firstLower = elementName.substring(0, 1).toLowerCase();
            String firstLowerMethodName = firstLower + elementName.substring(1);
            String[] getSetMethodArray = getSetMethodMap.get(firstLowerMethodName);
            if (getSetMethodArray == null) {
                continue;
            }
            Method setMethod = clazz.getMethod(getSetMethodArray[1], String.class);
            if (setMethod == null) {
                continue;
            }
            String elementText = element.getTextTrim();
            setMethod.invoke(t, StringUtils.isBlank(elementText) ? "" : elementText);
        }
        return t;
    }

    /**
     * 格式化XML字符串
     *
     * @param xml
     * @return
     */
    public static String formatXmlString(String xml) {
        StringWriter writer = new StringWriter();
        try {
            OutputFormat format = OutputFormat.createPrettyPrint();
            Document document = DocumentHelper.parseText(xml);
            // 格式化输出格式
            format.setEncoding("UTF-8");
            // 格式化输出流
            XMLWriter xmlWriter = new XMLWriter(writer, format);
            // 将document写入到输出流
            xmlWriter.write(document);
            xmlWriter.close();
        } catch (DocumentException e) {
            throw new SystemException(e);
        } catch (IOException e) {
            throw new SystemException(e);
        }
        return writer.toString();
    }

}
