// Path: src/main/java/io/xspec/maven/xspecMavenPlugin/resources/XSpecPluginResources.java
// public interface XSpecPluginResources {
//     public static final String XML_UTILITIES_PREFIX = "cp:/";
//     public static final String LOCAL_PREFIX = "cp:/";
//     public static final String CATALOG_NS = "urn:oasis:names:tc:entity:xmlns:xml:catalog";
//     
//     /**
//      * Returns URI for dependency scanner utility
//      * @return Dependency scanner URI
//      */
//     public String getDependencyScannerUri();
//     /**
//      * Image Down for folding report
//      * @return 
//      */
//     public String getImageDown();
//     
//     /**
//      * Image Up for folding report
//      * @return 
//      */
//     public String getImageUp();
//     
//     /**
//      * XSL that changes external images to inline images in folding report
//      * @return 
//      */
//     public String getXsltImageChanger();
// }


import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Properties;
import io.xspec.maven.xspecMavenPlugin.resources.XSpecPluginResources;
import javanet.staxutils.IndentingXMLStreamWriter;
import javax.xml.stream.XMLOutputFactory;
/**
 * Copyright © 2018, Christophe Marchand, XSpec organization
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package io.xspec.maven.xspecMavenPlugin.utils;



/**
 * This class writes a catalog
 * @author cmarchand
 */
public class CatalogWriter {

    public CatalogWriter(ClassLoader cl) throws XSpecPluginException {
        super();
    }

    /**
     * Generates and write a catalog that resolves all resources for XSpec,
     * schematron and plugin implementation. If XSpec execution requires a user
     * defined catalog, it may be specified in <tt>userCatalogFileName</tt>.<br/>
     * <tt>userCatalogFileName</tt> may be null ; no <tt>&lt;nextCatalog&gt;</tt> 
     * entry will be added to generated catalog.<br/>
     * If a non null value is provided for <tt>userCatalogFileName</tt>, then
     * a non null value <strong>must</strong> be provided for <tt>environment</tt> ;
     * else, a  IllegalArgumentException will be thrown.
     * @param userCatalogFilename The nextCatalog URI to add to generated catalog.
     * @param environment Environment properties, used to resolve all placeholders
     * in <tt>userCatalogFileName</tt>.
     * @param keepGeneratedCatalog Indicates if generated catalog must be kept after
     * plugin execution. If <tt>false</tt>, generated catalog will be deleted at
     * JVM exit.
     * @return Generated file
     * @throws XSpecPluginException
     * @throws IOException 
     */
    public File writeCatalog(String userCatalogFilename, Properties environment, boolean keepGeneratedCatalog) throws XSpecPluginException, IOException, IllegalArgumentException {
        if(userCatalogFilename!=null && environment==null) {
            throw new IllegalArgumentException("If you specify a userCatalogFilename, you must provide a non null environment.");
        }
        File tmpCatalog = File.createTempFile("tmp", "-catalog.xml");
        try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(tmpCatalog), Charset.forName("UTF-8"))) {
            XMLStreamWriter xmlWriter = XMLOutputFactory.newFactory().createXMLStreamWriter(osw);
            xmlWriter = new IndentingXMLStreamWriter(xmlWriter);
            xmlWriter.writeStartDocument("UTF-8", "1.0");
            xmlWriter.writeStartElement("catalog");
// Path: src/main/java/io/xspec/maven/xspecMavenPlugin/resources/XSpecPluginResources.java
// public interface XSpecPluginResources {
//     public static final String XML_UTILITIES_PREFIX = "cp:/";
//     public static final String LOCAL_PREFIX = "cp:/";
//     public static final String CATALOG_NS = "urn:oasis:names:tc:entity:xmlns:xml:catalog";
//     
//     /**
//      * Returns URI for dependency scanner utility
//      * @return Dependency scanner URI
//      */
//     public String getDependencyScannerUri();
//     /**
//      * Image Down for folding report
//      * @return 
//      */
//     public String getImageDown();
//     
//     /**
//      * Image Up for folding report
//      * @return 
//      */
//     public String getImageUp();
//     
//     /**
//      * XSL that changes external images to inline images in folding report
//      * @return 
//      */
//     public String getXsltImageChanger();
// }


// Path: src/main/java/io/xspec/maven/xspecMavenPlugin/utils/CatalogWriter.java
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Properties;
import io.xspec.maven.xspecMavenPlugin.resources.XSpecPluginResources;
import javanet.staxutils.IndentingXMLStreamWriter;
import javax.xml.stream.XMLOutputFactory;

/**
 * Copyright © 2018, Christophe Marchand, XSpec organization
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package io.xspec.maven.xspecMavenPlugin.utils;



/**
 * This class writes a catalog
 * @author cmarchand
 */
public class CatalogWriter {

    public CatalogWriter(ClassLoader cl) throws XSpecPluginException {
        super();
    }

    /**
     * Generates and write a catalog that resolves all resources for XSpec,
     * schematron and plugin implementation. If XSpec execution requires a user
     * defined catalog, it may be specified in <tt>userCatalogFileName</tt>.<br/>
     * <tt>userCatalogFileName</tt> may be null ; no <tt>&lt;nextCatalog&gt;</tt> 
     * entry will be added to generated catalog.<br/>
     * If a non null value is provided for <tt>userCatalogFileName</tt>, then
     * a non null value <strong>must</strong> be provided for <tt>environment</tt> ;
     * else, a  IllegalArgumentException will be thrown.
     * @param userCatalogFilename The nextCatalog URI to add to generated catalog.
     * @param environment Environment properties, used to resolve all placeholders
     * in <tt>userCatalogFileName</tt>.
     * @param keepGeneratedCatalog Indicates if generated catalog must be kept after
     * plugin execution. If <tt>false</tt>, generated catalog will be deleted at
     * JVM exit.
     * @return Generated file
     * @throws XSpecPluginException
     * @throws IOException 
     */
    public File writeCatalog(String userCatalogFilename, Properties environment, boolean keepGeneratedCatalog) throws XSpecPluginException, IOException, IllegalArgumentException {
        if(userCatalogFilename!=null && environment==null) {
            throw new IllegalArgumentException("If you specify a userCatalogFilename, you must provide a non null environment.");
        }
        File tmpCatalog = File.createTempFile("tmp", "-catalog.xml");
        try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(tmpCatalog), Charset.forName("UTF-8"))) {
            XMLStreamWriter xmlWriter = XMLOutputFactory.newFactory().createXMLStreamWriter(osw);
            xmlWriter = new IndentingXMLStreamWriter(xmlWriter);
            xmlWriter.writeStartDocument("UTF-8", "1.0");
            xmlWriter.writeStartElement("catalog");
            xmlWriter.setDefaultNamespace(XSpecPluginResources.CATALOG_NS);