package cn.reghao.tnb.sb.db.autobatis.mapper;

import cn.reghao.tnb.sb.db.autobatis.mapper.element.InsertElement;
import cn.reghao.tnb.sb.db.autobatis.mapper.element.MyBatisMapper;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.tree.DefaultAttribute;

import java.io.File;
import java.io.FileWriter;
import java.util.HashSet;
import java.util.Set;

/**
 * @author reghao
 * @date 2020-04-03 17:04:51
 */
public class XmlGenerator {
    /**
     * 创建 MyBatis mapper xml 文件
     *
     * @param
     * @return
     * @date 2020-04-03 下午10:10
     */
    public static void createMapperXml(MyBatisMapper myBatisMapper, File xmlFile) throws Exception {
        if (xmlFile.exists()) {
            return;
        }

        Document document = DocumentHelper.createDocument();
        document.addDocType("mapper",
                "-//mybatis.org//DTD Mapper 3.0//EN",
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd");

        Element mapper = document.addElement("mapper")
                .addAttribute("namespace", myBatisMapper.getNamespace());
        myBatisMapper.getElements().forEach(element -> {
            Element tmp = mapper.addElement(element.getName().name());
            element.getAttributes().forEach(tmp::addAttribute);
            element.getContent().forEach(tmp::addText);

            if (element instanceof InsertElement) {
                InsertElement insertElement = (InsertElement) element;
                InsertElement foreachElement = insertElement.getForeachElement();
                if (foreachElement != null) {
                    Element tmp1 = tmp.addElement(foreachElement.getName().name());
                    foreachElement.getAttributes().forEach(tmp1::addAttribute);
                    foreachElement.getContent().forEach(tmp1::addText);
                }
            }
        });

        OutputFormat outputFormat = new OutputFormat();
        outputFormat.setIndent(true);
        outputFormat.setIndentSize(4);
        outputFormat.setNewlines(true);
        outputFormat.setPadText(true);

        XMLWriter writer = new XMLWriter(new FileWriter(xmlFile), outputFormat);
        writer.write(document);
        writer.flush();
        writer.close();
    }

    /**
     * 在 mybatis config 中注册 mapper 接口
     *
     * @param parent 父节点
     * @param element 待添加的子节点
     * @param attribute 子节点的属性
     * @param value 子节点的属性值
     *
     * @date 2020-04-03 下午5:20
     */
    public static void registerMapper(File xmlFile, String parent, String element, String attribute, String value)
            throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(xmlFile);
        Element parentNode = document.getRootElement().element(parent);

        Set<String> attributeValues = new HashSet<>();
        parentNode.elements().forEach(element1 -> {
            String attrValue = element1.attribute(attribute).getValue();
            attributeValues.add(attrValue.substring(attrValue.lastIndexOf("/")));
        });

        // 若 mapper 已注册则不处理
        if (attributeValues.contains(value.substring(value.lastIndexOf("/")))) {
            return;
        }

        Element newElement = parentNode.addElement(element);
        Attribute attr = new DefaultAttribute(attribute, value);
        newElement.add(attr);

        XMLWriter writer = new XMLWriter(new FileWriter(xmlFile));
        writer.write(document);
        writer.flush();
        writer.close();
    }
}
