/*
 * 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.ws.commons.om.infoset;

import org.apache.ws.commons.om.OMAbstractFactory;
import org.apache.ws.commons.om.OMDocument;
import org.apache.ws.commons.om.OMElement;
import org.apache.ws.commons.om.impl.llom.builder.StAXOMBuilder;
import org.apache.ws.commons.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('\\','/');
    }
}
