package seng302.DataInput;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * Created by fwy13 on 26/03/2017.
 */
public abstract class XMLReader {

    protected Document doc;

    /**
     * Read in XML file
     * @param filePath filepath for XML file
     * @throws ParserConfigurationException If a document builder cannot be created.
     * @throws IOException If any IO errors occur while parsing the XML file.
     * @throws SAXException If any parse error occurs while parsing.
     */
    public XMLReader(String filePath) throws ParserConfigurationException, IOException, SAXException {

        InputSource fXmlFile;
        if (filePath.contains("<")) {
            fXmlFile = new InputSource();
            fXmlFile.setCharacterStream(new StringReader(filePath));

        } else {
            fXmlFile = new InputSource(getClass().getClassLoader().getResourceAsStream(filePath));
        }

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        doc = dBuilder.parse(fXmlFile);
        doc.getDocumentElement().normalize();
    }

    public XMLReader(String xmlFile, Boolean isWholeFile) {

    }

    /**
     * Return Document data of the read-in XML
     * @return XML document
     */
    public Document getDocument() {
        return doc;
    }

    /**
     * Get content of a tag in an element
     * @param n Element to read tags from
     * @param tagName Name of the tag
     * @return Content of the tag
     */
    public String getTextValueOfNode(Element n, String tagName) {
        return n.getElementsByTagName(tagName).item(0).getTextContent();
    }

    /**
     * Get attributes for an element
     * @param n Element to read attributes from
     * @param attr Attributes of element
     * @return Attributes of element
     */
    public String getAttribute(Element n, String attr) {
        return n.getAttribute(attr);
    }

    protected boolean exists(Node node, String attribute) {
        return node.getAttributes().getNamedItem(attribute) != null;
    }

    public static String getContents(Document document) throws TransformerException {
        DOMSource source = new DOMSource(document);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        StringWriter stringWriter = new StringWriter();
        StreamResult result = new StreamResult(stringWriter);
        transformer.transform(source, result);

        return stringWriter.toString();
    }

}
