package net.northking.cctp.attachment.util;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;

public class XMLUtils {
    private static ThreadLocal<XPath> XPATH = new ThreadLocal<>();

    public static Document getDocument(String xmlText) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        String FEATURE = null;
        FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
        dbf.setFeature(FEATURE, true);
        FEATURE = "http://xml.org/sax/features/external-general-entities";
        dbf.setFeature(FEATURE, false);
        FEATURE = "http://xml.org/sax/features/external-parameter-entities";
        dbf.setFeature(FEATURE, false);
        FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
        dbf.setFeature(FEATURE, false);
        dbf.setXIncludeAware(false);
        dbf.setExpandEntityReferences(false);

        dbf.setValidating(false);
        DocumentBuilder db = dbf.newDocumentBuilder();
        InputStream resourceAsStream = new ByteArrayInputStream(xmlText.getBytes(Charset.forName("UTF-8")));
        return db.parse(resourceAsStream);
    }
    public static Document getDocument(File file) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        String FEATURE = null;
        FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
        dbf.setFeature(FEATURE, true);
        FEATURE = "http://xml.org/sax/features/external-general-entities";
        dbf.setFeature(FEATURE, false);
        FEATURE = "http://xml.org/sax/features/external-parameter-entities";
        dbf.setFeature(FEATURE, false);
        FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
        dbf.setFeature(FEATURE, false);
        dbf.setXIncludeAware(false);
        dbf.setExpandEntityReferences(false);

        dbf.setValidating(false);
        DocumentBuilder db = dbf.newDocumentBuilder();
        InputStream resourceAsStream = new FileInputStream(file);
        return db.parse(resourceAsStream);
    }
    public static Node getNode(Document doc, String xpath) throws Exception {
        return (Node)(getXPath().evaluate(xpath, doc, XPathConstants.NODE));
    }

    public static String getValue(Document doc,String xpath) throws Exception {
        return (String)getXPath().evaluate(xpath, doc,XPathConstants.STRING);
    }

    public static void main(String[] args) throws Exception {
        Document doc = getDocument(new File("main.xml"));
        Node node = getNode(doc, "//activity[intent-filter/action[@name='android.intent.action.MAIN']]");
        System.out.println(node.getNodeName());

        System.out.println(getValue(doc, "//activity[intent-filter/action[@name='android.intent.action.MAIN']]/@name"));
    }

    private static XPath getXPath(){
        XPath xPath = XPATH.get();
        if (xPath == null){
            xPath = XPathFactory.newInstance().newXPath();
            XPATH.set(xPath);
        }
        return xPath;
    }
}
