package com.lantone.qc.dbanaly.facade.comsis;

import com.lantone.qc.pub.util.EnDecodeUtil;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: xml公共处理
 * @author: rengb
 * @time: 2020/4/17 15:16
 */
public class XmlUtil {

    private static String LESS_THAN_SYMBOL_REPLACE = "th@xyh";
    private static String START_SURROUND_SYMBOL = "th@ksxyh";
    private static String END_SURROUND_SYMBOL = "th@jsdyh";

    /**
     * 纠正xml内容，将因为不规范而影响dom4j解析的部分先替换掉，解析完后再替换回来
     *
     * @param xml
     * @return
     */
    public static String xmlErrorCorrection(String xml) {
        xml = xml.replaceAll("\\<\\?xml[\\S\\s][^<>]*\\?\\>", "");
        StringBuffer sbf = new StringBuffer();
        Pattern pattern = Pattern.compile("\\<.[^<>]*\\>");
        Matcher matcher = pattern.matcher(xml);
        int start = 0, end = 0;
        String xmlCopy = xml, elementName = null, elementNameReplace = null;
        while (matcher.find()) {
            elementName = matcher.group();
            start = matcher.start();
            if (end > 0 && start > 0 && end < start) {
                sbf.append(xml.substring(end, start).replaceAll("<", LESS_THAN_SYMBOL_REPLACE));
            }
            if (isCorrectXmlElement(elementName, xmlCopy)) {
                sbf.append(elementName);
            } else {
                elementNameReplace = START_SURROUND_SYMBOL + EnDecodeUtil.encode(elementName) + END_SURROUND_SYMBOL;
                xmlCopy = xmlCopy.replace(elementName, elementNameReplace);
                sbf.append(elementNameReplace);
            }
            end = matcher.end();
        }
        return sbf.toString();
    }

    /**
     * 判断某个xml标签，在当前xml文档中，是否是正常的xml标签
     *
     * @param elementName 标签
     * @param xml         当前xml文档
     * @return
     */
    public static boolean isCorrectXmlElement(String elementName, String xml) {
        //过滤类型：<>、< abc>
        if (elementName.length() == 2 || elementName.indexOf(" ") == 1) {
            return false;
        }
        //过滤类型：<abc/ >
        String elementNameCopy = elementName.substring(1, elementName.length() - 1).trim();
        if (elementNameCopy.endsWith("/") && elementName.lastIndexOf(" ") == elementName.length() - 2) {
            return false;
        }
        //过滤类型：有<abc>，而没有</abc>
        if (!elementNameCopy.endsWith("/")) {
            if (elementNameCopy.startsWith("/")) {
                Pattern pattern = Pattern.compile("\\<" + elementNameCopy.substring(1) + ".[^<>]*\\>");
                Matcher matcher = pattern.matcher(xml);
                if (xml.indexOf("<" + elementNameCopy.substring(1) + ">") == -1 && !matcher.find()) {
                    return false;
                }
            } else {
                int firstBlankIndex = elementNameCopy.indexOf(" ");
                firstBlankIndex = firstBlankIndex == -1 ? elementNameCopy.length() : firstBlankIndex;
                elementNameCopy = elementNameCopy.substring(0, firstBlankIndex);
                if (xml.indexOf("</" + elementNameCopy + ">") == -1) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 对由xml解析得到的map进行遍历，将value值中被替换的部分还原回来，
     *
     * @param sourceMap
     * @return
     */
    public static Map<String, String> correctMapOfXml(Map<String, String> sourceMap) {
        Pattern pattern = Pattern.compile(START_SURROUND_SYMBOL + ".*" + END_SURROUND_SYMBOL);
        String value = null, valueCopy = null, matMsg = null;
        Matcher matcher = null;
        for (String key : sourceMap.keySet()) {
            value = sourceMap.get(key);
            valueCopy = value;
            valueCopy = valueCopy.replaceAll(LESS_THAN_SYMBOL_REPLACE, "<");
            matcher = pattern.matcher(value);
            while (matcher.find()) {
                matMsg = matcher.group();
                valueCopy = valueCopy.replace(matMsg,
                        EnDecodeUtil.decode(
                                matMsg.replace(START_SURROUND_SYMBOL, "").replace(END_SURROUND_SYMBOL, "")
                        )
                );
            }
            sourceMap.put(key, valueCopy);
        }
        return sourceMap;
    }

}