/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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
 *
 *      https://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.tools.ant.taskdefs.optional;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.XSLTLiaison4;
import org.apache.tools.ant.taskdefs.XSLTLogger;
import org.apache.tools.ant.taskdefs.XSLTLoggerAware;
import org.apache.tools.ant.taskdefs.XSLTProcess;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.XMLCatalog;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.URLProvider;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JAXPUtils;
import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.StreamUtils;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1)
 *
 * @since Ant 1.3
 */
public class TraXLiaison implements XSLTLiaison4, ErrorListener, XSLTLoggerAware {

    /**
     * Helper for transforming filenames to URIs.
     *
     * @since Ant 1.7
     */
    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    /**
     * The current <code>Project</code>
     */
    private Project project;

    /**
     * the name of the factory implementation class to use
     * or null for default JAXP lookup.
     */
    private String factoryName = null;

    /** The trax TransformerFactory */
    private TransformerFactory tfactory = null;

    /** stylesheet to use for transformation */
    private Resource stylesheet;

    private XSLTLogger logger;

    /** possible resolver for publicIds */
    private EntityResolver entityResolver;

    /** transformer to use for processing files */
    private Transformer transformer;

    /** The In memory version of the stylesheet */
    private Templates templates;

    /**
     * The modification time of the stylesheet from which the templates
     * are read
     */
    private long templatesModTime;

    /** possible resolver for URIs */
    private URIResolver uriResolver;

    /** transformer output properties */
    private final Vector<String[]> outputProperties = new Vector<>();

    /** stylesheet parameters */
    private final Hashtable<String, Object> params = new Hashtable<>();

    /** factory attributes */
    private final List<Object[]> attributes = new ArrayList<>();

    /** factory features */
    private final Map<String, Boolean> features = new HashMap<>();

    /** whether to suppress warnings */
    private boolean suppressWarnings = false;

    /** optional trace configuration. */
    private XSLTProcess.TraceConfiguration traceConfiguration = null;

    /**
     * Constructor for TraXLiaison.
     * @throws Exception never
     */
    public TraXLiaison() throws Exception { //NOSONAR
    }

    /**
     * Set the stylesheet file.
     * @param stylesheet a <code>File</code> value
     * @throws Exception on error
     */
    public void setStylesheet(final File stylesheet) throws Exception {
        final FileResource fr = new FileResource();
        fr.setProject(project);
        fr.setFile(stylesheet);
        setStylesheet(fr);
    }

    /**
     * Set the stylesheet file.
     * @param stylesheet a {@link org.apache.tools.ant.types.Resource} value
     * @throws Exception on error
     */
    public void setStylesheet(final Resource stylesheet) throws Exception {
        if (this.stylesheet != null) {
            // resetting the stylesheet - reset transformer
            transformer = null;

            // do we need to reset templates as well
            if (!this.stylesheet.equals(stylesheet)
                || (stylesheet.getLastModified() != templatesModTime)) {
                templates = null;
            }
        }
        this.stylesheet = stylesheet;
    }

    /**
     * Transform an input file.
     * @param infile the file to transform
     * @param outfile the result file
     * @throws Exception on error
     */
    public void transform(final File infile, final File outfile) throws Exception {
        if (transformer == null) {
            createTransformer();
        }

        // autoclose all handles, otherwise the garbage collector will close them...
        // and Windows may complain about not being able to delete files.
        try (InputStream fis = new BufferedInputStream(Files.newInputStream(infile.toPath()));
             OutputStream fos = new BufferedOutputStream(Files.newOutputStream(outfile.toPath()))) {
            final StreamResult res = new StreamResult(fos);
            // not sure what could be the need of this...
            res.setSystemId(JAXPUtils.getSystemId(outfile));
            // set parameters on each transformation, maybe something has changed
            //(e.g. value of file name parameter)
            setTransformationParameters();

            transformer.transform(getSource(fis, infile), res);
        }
    }

    /**
     * Get the source instance from the stream and id of the file.
     * @param is the stream containing the stylesheet data.
     * @param infile the file that will be used for the systemid.
     * @return the configured source instance matching the stylesheet.
     * @throws ParserConfigurationException if a parser cannot be created which
     * satisfies the requested configuration.
     * @throws SAXException in case of problem detected by the SAX parser.
     */
    private Source getSource(final InputStream is, final File infile)
        throws ParserConfigurationException, SAXException {
        // todo: is this comment still relevant ??
        // FIXME: need to use a SAXSource as the source for the transform
        // so we can plug in our own entity resolver
        Source src = null;
        if (entityResolver != null) {
            if (getFactory().getFeature(SAXSource.FEATURE)) {
                final SAXParserFactory spFactory = SAXParserFactory.newInstance();
                spFactory.setNamespaceAware(true);
                final XMLReader reader = spFactory.newSAXParser().getXMLReader();
                reader.setEntityResolver(entityResolver);
                src = new SAXSource(reader, new InputSource(is));
            } else {
                throw new IllegalStateException("xcatalog specified, but "
                    + "parser doesn't support SAX");
            }
        } else {
            // WARN: Don't use the StreamSource(File) ctor. It won't work with
            // xalan prior to 2.2 because of systemid bugs.
            src = new StreamSource(is);
        }
        src.setSystemId(JAXPUtils.getSystemId(infile));
        return src;
    }

    private Source getSource(final InputStream is, final Resource resource)
        throws ParserConfigurationException, SAXException {
        // todo: is this comment still relevant ??
        // FIXME: need to use a SAXSource as the source for the transform
        // so we can plug in our own entity resolver
        Source src = null;
        if (entityResolver != null) {
            if (getFactory().getFeature(SAXSource.FEATURE)) {
                final SAXParserFactory spFactory = SAXParserFactory.newInstance();
                spFactory.setNamespaceAware(true);
                final XMLReader reader = spFactory.newSAXParser().getXMLReader();
                reader.setEntityResolver(entityResolver);
                src = new SAXSource(reader, new InputSource(is));
            } else {
                throw new IllegalStateException("xcatalog specified, but "
                    + "parser doesn't support SAX");
            }
        } else {
            // WARN: Don't use the StreamSource(File) ctor. It won't work with
            // xalan prior to 2.2 because of systemid bugs.
            src = new StreamSource(is);
        }
        // The line below is a hack: the system id must an URI, but it is not
        // cleat to get the URI of an resource, so just set the name of the
        // resource as a system id
        src.setSystemId(resourceToURI(resource));
        return src;
    }

    private String resourceToURI(final Resource resource) {
        final FileProvider fp = resource.as(FileProvider.class);
        if (fp != null) {
            return FILE_UTILS.toURI(fp.getFile().getAbsolutePath());
        }
        final URLProvider up = resource.as(URLProvider.class);
        if (up != null) {
            final URL u = up.getURL();
            return String.valueOf(u);
        } else {
            return resource.getName();
        }
    }

    /**
     * Read in templates from the stylesheet
     */
    private void readTemplates()
        throws IOException, TransformerConfigurationException,
               ParserConfigurationException, SAXException {

        // Use a stream so that you can close it yourself quickly
        // and avoid keeping the handle until the object is garbaged.
        // (always keep control), otherwise you won't be able to delete
        // the file quickly on windows.
        try (InputStream xslStream =
             new BufferedInputStream(stylesheet.getInputStream())) {
            templatesModTime = stylesheet.getLastModified();
            final Source src = getSource(xslStream, stylesheet);
            templates = getFactory().newTemplates(src);
        }
    }

    /**
     * Create a new transformer based on the liaison settings
     * @see #setStylesheet(java.io.File)
     * @see #addParam(java.lang.String, java.lang.String)
     * @see #setOutputProperty(java.lang.String, java.lang.String)
     */
    private void createTransformer()
        throws IOException, ParserConfigurationException, SAXException, TransformerException {
        if (templates == null) {
            readTemplates();
        }

        transformer = templates.newTransformer();

        // configure the transformer...
        transformer.setErrorListener(this);
        if (uriResolver != null) {
            transformer.setURIResolver(uriResolver);
        }
        for (final String[] pair : outputProperties) {
            transformer.setOutputProperty(pair[0], pair[1]);
        }

        if (traceConfiguration != null) {
            if ("org.apache.xalan.transformer.TransformerImpl" //NOSONAR
                .equals(transformer.getClass().getName())) {
                try {
                    final Class<?> traceSupport =
                        Class.forName("org.apache.tools.ant.taskdefs.optional."
                                      + "Xalan2TraceSupport", true,
                                      Thread.currentThread()
                                      .getContextClassLoader());
                    final XSLTTraceSupport ts =
                        (XSLTTraceSupport) traceSupport.newInstance();
                    ts.configureTrace(transformer, traceConfiguration);
                } catch (final Exception e) {
                    final String msg = "Failed to enable tracing because of " + e;
                    if (project != null) {
                        project.log(msg, Project.MSG_WARN);
                    } else {
                        System.err.println(msg);
                    }
                }
            } else {
                final String msg = "Not enabling trace support for transformer"
                    + " implementation" + transformer.getClass().getName();
                if (project != null) {
                    project.log(msg, Project.MSG_WARN);
                } else {
                    System.err.println(msg);
                }
            }
        }
    }

    /**
     * Sets the parameters for the transformer.
     */
    private void setTransformationParameters() {
        params.forEach((key, value) -> transformer.setParameter(key, value));
    }

    /**
     * return the Transformer factory associated to this liaison.
     * @return the Transformer factory associated to this liaison.
     * @throws BuildException thrown if there is a problem creating
     * the factory.
     * @see #setFactory(String)
     * @since Ant 1.5.2
     */
    private TransformerFactory getFactory() throws BuildException {
        if (tfactory != null) {
            return tfactory;
        }
        // not initialized yet, so create the factory
        if (factoryName == null) {
            tfactory = TransformerFactory.newInstance();
        } else {
            try {
                Class<?> clazz = null;
                try {
                    clazz =
                        Class.forName(factoryName, true,
                                      Thread.currentThread()
                                      .getContextClassLoader());
                } catch (final ClassNotFoundException cnfe) {
                    final String msg = "Failed to load " + factoryName
                        + " via the configured classpath, will try"
                        + " Ant's classpath instead.";
                    if (logger != null) {
                        logger.log(msg);
                    } else if (project != null) {
                        project.log(msg, Project.MSG_WARN);
                    } else {
                        System.err.println(msg);
                    }
                }

                if (clazz == null) {
                    clazz = Class.forName(factoryName);
                }
                tfactory = (TransformerFactory) clazz.newInstance();
            } catch (final Exception e) {
                throw new BuildException(e);
            }
        }

        applyReflectionHackForExtensionMethods();

        tfactory.setErrorListener(this);

        // specific attributes for the transformer
        for (final Object[] pair : attributes) {
            tfactory.setAttribute((String) pair[0], pair[1]);
        }

        for (Map.Entry<String, Boolean> feature : features.entrySet()) {
            try {
                tfactory.setFeature(feature.getKey(), feature.getValue());
            } catch (TransformerConfigurationException ex) {
                throw new BuildException(ex);
            }
        }

        if (uriResolver != null) {
            tfactory.setURIResolver(uriResolver);
        }
        return tfactory;
    }

    /**
     * Set the factory name to use instead of JAXP default lookup.
     * @param name the fully qualified class name of the factory to use
     * or null for the default JAXP look up mechanism.
     * @since Ant 1.6
     */
    public void setFactory(final String name) {
        factoryName = name;
    }

    /**
     * Set a custom attribute for the JAXP factory implementation.
     * @param name the attribute name.
     * @param value the value of the attribute, usually a boolean
     * string or object.
     * @since Ant 1.6
     */
    public void setAttribute(final String name, final Object value) {
        final Object[] pair = new Object[]{name, value};
        attributes.add(pair);
    }

    /**
     * Set a custom feature for the JAXP factory implementation.
     * @param name the feature name.
     * @param value the value of the feature
     * @since Ant 1.9.8
     */
    public void setFeature(final String name, final boolean value) {
        features.put(name, value);
    }

    /**
     * Set the output property for the current transformer.
     * Note that the stylesheet must be set prior to calling
     * this method.
     * @param name the output property name.
     * @param value the output property value.
     * @since Ant 1.5
     * @since Ant 1.5
     */
    public void setOutputProperty(final String name, final String value) {
        final String[] pair = new String[]{name, value};
        outputProperties.addElement(pair);
    }

    /**
     * Set the class to resolve entities during the transformation.
     * @param aResolver the resolver class.
     */
    public void setEntityResolver(final EntityResolver aResolver) {
        entityResolver = aResolver;
    }

    /**
     * Set the class to resolve URIs during the transformation
     * @param aResolver a <code>EntityResolver</code> value
     */
    public void setURIResolver(final URIResolver aResolver) {
        uriResolver = aResolver;
    }

    /**
     * Add a parameter.
     * @param name the name of the parameter
     * @param value the value of the parameter
     */
    public void addParam(final String name, final String value) {
        params.put(name, value);
    }

    /**
     * Add a parameter.
     * @param name the name of the parameter
     * @param value the value of the parameter
     * @since Ant 1.9.3
     */
    public void addParam(final String name, final Object value) {
        params.put(name, value);
    }

    /**
     * Set a logger.
     * @param l a logger.
     */
    public void setLogger(final XSLTLogger l) {
        logger = l;
    }

    /**
     * Log an error.
     * @param e the exception to log.
     */
    public void error(final TransformerException e) {
        logError(e, "Error");
    }

    /**
     * Log a fatal error.
     * @param e the exception to log.
     */
    public void fatalError(final TransformerException e) {
        logError(e, "Fatal Error");
        throw new BuildException("Fatal error during transformation using " + stylesheet + ": " + e.getMessageAndLocation(), e);
    }

    /**
     * Log a warning.
     * @param e the exception to log.
     */
    public void warning(final TransformerException e) {
        if (!suppressWarnings) {
            logError(e, "Warning");
        }
    }

    private void logError(final TransformerException e, final String type) {
        if (logger == null) {
            return;
        }

        final StringBuffer msg = new StringBuffer();
        final SourceLocator locator = e.getLocator();
        if (locator != null) {
            final String systemid = locator.getSystemId();
            if (systemid != null) {
                String url = systemid;
                if (url.startsWith("file:")) {
                    url = FileUtils.getFileUtils().fromURI(url);
                }
                msg.append(url);
            } else {
                msg.append("Unknown file");
            }
            final int line = locator.getLineNumber();
            if (line != -1) {
                msg.append(":");
                msg.append(line);
                final int column = locator.getColumnNumber();
                if (column != -1) {
                    msg.append(":");
                    msg.append(column);
                }
            }
        }
        msg.append(": ");
        msg.append(type);
        msg.append("! ");
        msg.append(e.getMessage());
        if (e.getCause() != null) {
            msg.append(" Cause: ");
            msg.append(e.getCause());
        }

        logger.log(msg.toString());
    }

    // kept for backwards compatibility
    /**
     * @param file the filename to use for the systemid
     * @return the systemid
     * @deprecated since 1.5.x.
     *             Use org.apache.tools.ant.util.JAXPUtils#getSystemId instead.
     */
    @Deprecated
    protected String getSystemId(final File file) {
        return JAXPUtils.getSystemId(file);
    }


    /**
     * Specific configuration for the TRaX liaison.
     * @param xsltTask the XSLTProcess task instance from which this liaison
     *        is to be configured.
     */
    public void configure(final XSLTProcess xsltTask) {
        project = xsltTask.getProject();
        final XSLTProcess.Factory factory = xsltTask.getFactory();
        if (factory != null) {
            setFactory(factory.getName());
            // configure factory attributes
            StreamUtils.enumerationAsStream(factory.getAttributes())
                    .forEach(attr -> setAttribute(attr.getName(), attr.getValue()));
            factory.getFeatures()
                    .forEach(feature -> setFeature(feature.getName(), feature.getValue()));
        }

        final XMLCatalog xmlCatalog = xsltTask.getXMLCatalog();
        // use XMLCatalog as the entity resolver and URI resolver
        if (xmlCatalog != null) {
            setEntityResolver(xmlCatalog);
            setURIResolver(xmlCatalog);
        }

        // configure output properties
        StreamUtils.enumerationAsStream(xsltTask.getOutputProperties())
                .forEach(prop -> setOutputProperty(prop.getName(), prop.getValue()));

        suppressWarnings = xsltTask.getSuppressWarnings();

        traceConfiguration = xsltTask.getTraceConfiguration();
    }

    private void applyReflectionHackForExtensionMethods() {
        // Jigsaw doesn't allow reflection to work, so we can stop trying
        if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
            try { // #51668, #52382
                final Field _isNotSecureProcessing = tfactory.getClass().getDeclaredField("_isNotSecureProcessing");
                _isNotSecureProcessing.setAccessible(true);
                _isNotSecureProcessing.set(tfactory, Boolean.TRUE);
            } catch (final Exception x) {
                if (project != null) {
                    project.log(x.toString(), Project.MSG_DEBUG);
                }
            }
        }
    }

}
