/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.axiom.om.infoset;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.factory.OMXMLBuilderFactory;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLTestCase;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
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.stream.XMLInputFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class XMLConformanceUnit extends XMLTestCase implements EntityResolver {

    private String filePath;
    private File directory;

    public XMLConformanceUnit(String filePath, String testName) {
        super(testName);
        this.filePath = filePath;
        this.directory = new File(filePath).getParentFile();
    }

    public void testSingleFileConformance()
            throws Exception {
        OMElement rootElement;

        System.out.println("XML File:" + filePath);
        XMLInputFactory factory = XMLInputFactory.newInstance();
//        factory.setProperty("report-cdata-event", Boolean.TRUE);
        StAXOMBuilder staxOMBuilder = OMXMLBuilderFactory.
                createStAXOMBuilder(OMAbstractFactory.getOMFactory(),
                        factory.createXMLStreamReader(
                                new FileInputStream(filePath)));
        rootElement = staxOMBuilder.getDocumentElement();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ((OMDocument)rootElement.getParent()).serialize(baos);

        InputSource resultXML = new InputSource(new InputStreamReader(
                new ByteArrayInputStream(baos.toByteArray())));

        Document dom1 = newDocument(new InputSource(new FileReader(filePath)));
        Document dom2 = newDocument(resultXML);

        Diff diff = compareXML(dom1, dom2);
        assertXMLEqual(diff, true);
    }

    /**
     * Method newDocument
     *
     * @param in
     * @return
     * @throws javax.xml.parsers.ParserConfigurationException
     *
     * @throws org.xml.sax.SAXException
     * @throws java.io.IOException
     */
    public Document newDocument(InputSource in)
            throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        db.setEntityResolver(this);
        return db.parse(in);
    }

    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
        File f = new File(directory, systemId.substring(systemId.lastIndexOf('/')));
        return new InputSource(new FileInputStream(f));
    }

    public String getName() {
        String name = filePath;
        if(name.lastIndexOf("xmlconf")!=-1)
            name = name.substring(name.lastIndexOf("xmlconf"));
        return name.replace('\\','/');
    }
}
