package usda.weru.soil.arssql;

import de.schlichtherle.truezip.file.TFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParserFactory;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import usda.weru.util.Util;

/**
 *
 * @author maxerdwien
 */
public class SAXParse extends DefaultHandler {

    private static final Logger LOGGER = Logger.getLogger(SAXParse.class);
    private int inSchema = 0;
    int numRows = 0;
    private final Map<String, List<String>> ht = new HashMap<String, List<String>>();
    private String tagName = null;
    java.lang.StringBuffer buffer = new java.lang.StringBuffer();

    /**
     *
     * @return
     */
    public int getLength() {
        return numRows;
    }

    /**
     *
     * @param file
     * @return
     */
    public static SAXParse parse(TFile file) {
        // Use an instance of ourselves as the SAX event handler
        SAXParse handler = new SAXParse();
        // Use the default (non-validating) parser
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            // Parse the input
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse(file, handler);

        } catch (IOException | ParserConfigurationException | SAXException t) {
            JOptionPane.showMessageDialog(null, "Unable to parse Soil Data Mart response:\n"
                    + t.getLocalizedMessage(), "Parsing Error", JOptionPane.ERROR_MESSAGE);
            LOGGER.error("Unable to parse xml file: " + file.getAbsolutePath() + "\n" + Util.fileContents(file), t);
        }
        return handler;
    }

    /**
     *
     * @param fileName
     * @return
     */
    public static SAXParse parse(String fileName) {
        return parse(new TFile(fileName));
    }

//    private int indentLevel = 0;
    //===========================================================
    // SAX DocumentHandler methods
    //===========================================================
    /**
     *
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        //System.out.println("START DOCUMENT");
    }

    /**
     *
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
        //System.out.println("END DOCUMENT");
    }

    /**
     *
     * @param namespaceURI
     * @param lName local name
     * @param qName qualified name
     * @param attrs
     * @throws SAXException
     */
    @Override
    public void startElement(String namespaceURI,
            String lName,
            String qName,
            Attributes attrs) throws SAXException {

        if (qName.equals("xs:schema")) {
            inSchema++;
            return;
        }

        if ((inSchema == 1) && qName.equals("xs:element")) {
            Object rtn = ht.get(attrs.getValue(0));
            if (rtn != null) {
                System.out.println("duplicate hash key " + attrs.getValue(0));
            } else {
                ht.put(attrs.getValue(0), new ArrayList<String>());
            }
        }

        if ((inSchema == 2)) {
            tagName = qName;
            buffer.setLength(0);
        }
    }

    /**
     *
     * @param namespaceURI
     * @param sName simple name
     * @param qName qualified name
     * @throws SAXException
     */
    @Override
    public void endElement(String namespaceURI,
            String sName,
            String qName
    ) throws SAXException {

        if (qName.equals("xs:schema")) {
            inSchema++;
            //System.out.println("exit schema " + inSchema);
        }
        if (inSchema == 2 && tagName != null) {
            List<String> tmpVec = ht.get(tagName);
            if (tmpVec != null) {
                tmpVec.add(buffer.toString());
                numRows = tmpVec.size();
            }
            tagName = null;
        }
    }

    /**
     *
     * @param buf
     * @param offset
     * @param len
     * @throws SAXException
     */
    @Override
    public void characters(char buf[], int offset, int len) throws SAXException {
        String s = new String(buf, offset, len);
        s = s.trim();
        buffer.append(s);
    }

    /**
     *
     * @param tagName
     * @return
     */
    public List<String> getColumn(String tagName) {
        return ht.get(tagName);
    }

}
