/*
 * 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
 *
 *      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.camel.component.xslt.saxon;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.transform.TransformerFactory;

import net.sf.saxon.Configuration;
import net.sf.saxon.TransformerFactoryImpl;
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
import org.apache.camel.api.management.ManagedAttribute;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.component.xslt.XsltEndpoint;
import org.apache.camel.spi.ClassResolver;
import org.apache.camel.spi.Injector;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.support.EndpointHelper;

/**
 * Transforms the message using a XSLT template using Saxon.
 */
@ManagedResource(description = "Managed XsltSaxonEndpoint")
@UriEndpoint(firstVersion = "3.0.0", scheme = "xslt-saxon", title = "XSLT Saxon", syntax = "xslt-saxon:resourceUri", producerOnly = true, label = "core,transformation")
public class XsltSaxonEndpoint extends XsltEndpoint {
    @UriParam(label = "advanced")
    private Configuration saxonConfiguration;
    @Metadata(label = "advanced")
    private Map<String, Object> saxonConfigurationProperties = new HashMap<>();
    @UriParam(label = "advanced", javaType = "java.lang.String")
    private List<Object> saxonExtensionFunctions;
    @UriParam(displayName = "Allow StAX", defaultValue = "true")
    private boolean allowStAX = true;

    public XsltSaxonEndpoint(String endpointUri, Component component) {
        super(endpointUri, component);
    }

    public List<Object> getSaxonExtensionFunctions() {
        return saxonExtensionFunctions;
    }

    /**
     * Allows you to use a custom net.sf.saxon.lib.ExtensionFunctionDefinition.
     * You would need to add camel-saxon to the classpath.
     * The function is looked up in the registry, where you can comma to separate multiple values to lookup.
     */
    public void setSaxonExtensionFunctions(List<Object> extensionFunctions) {
        this.saxonExtensionFunctions = extensionFunctions;
    }

    /**
     * Allows you to use a custom net.sf.saxon.lib.ExtensionFunctionDefinition.
     * You would need to add camel-saxon to the classpath.
     * The function is looked up in the registry, where you can comma to separate multiple values to lookup.
     */
    public void setSaxonExtensionFunctions(String extensionFunctions) {
        this.saxonExtensionFunctions = EndpointHelper.resolveReferenceListParameter(
            getCamelContext(),
            extensionFunctions,
            Object.class
        );
    }

    public Configuration getSaxonConfiguration() {
        return saxonConfiguration;
    }

    /**
     * To use a custom Saxon configuration
     */
    public void setSaxonConfiguration(Configuration saxonConfiguration) {
        this.saxonConfiguration = saxonConfiguration;
    }

    public Map<String, Object> getSaxonConfigurationProperties() {
        return saxonConfigurationProperties;
    }

    /**
     * To set custom Saxon configuration properties
     */
    public void setSaxonConfigurationProperties(Map<String, Object> configurationProperties) {
        this.saxonConfigurationProperties = configurationProperties;
    }

    @ManagedAttribute(description = "Whether to allow using StAX as the javax.xml.transform.Source")
    public boolean isAllowStAX() {
        return allowStAX;
    }

    /**
     * Whether to allow using StAX as the javax.xml.transform.Source.
     * You can enable this if the XSLT library supports StAX such as the Saxon library (camel-saxon).
     * The Xalan library (default in JVM) does not support StAXSource.
     */
    public void setAllowStAX(boolean allowStAX) {
        this.allowStAX = allowStAX;
    }

    @Override
    protected void doStart() throws Exception {
        // the processor is the xslt builder
        setXslt(createXsltBuilder());
        setProcessor(getXslt());
    }

    protected XsltSaxonBuilder createXsltBuilder() throws Exception {
        final CamelContext ctx = getCamelContext();
        final ClassResolver resolver = ctx.getClassResolver();
        final Injector injector = ctx.getInjector();

        log.debug("{} using schema resource: {}", this, getResourceUri());

        final XsltSaxonBuilder xslt = injector.newInstance(XsltSaxonBuilder.class);

        TransformerFactory factory = getTransformerFactory();
        if (factory == null) {
            if (getTransformerFactoryClass() == null) {
                // create new saxon factory
                factory = new TransformerFactoryImpl();
            } else {
                // provide the class loader of this component to work in OSGi environments
                Class<TransformerFactory> factoryClass = resolver.resolveMandatoryClass(getTransformerFactoryClass(), TransformerFactory.class, XsltSaxonComponent.class.getClassLoader());
                log.debug("Using TransformerFactoryClass {}", factoryClass);
                factory = injector.newInstance(factoryClass);
            }
        }

        if (factory instanceof TransformerFactoryImpl) {
            TransformerFactoryImpl tf = (TransformerFactoryImpl) factory;
            XsltSaxonHelper.registerSaxonConfiguration(tf, saxonConfiguration);
            XsltSaxonHelper.registerSaxonConfigurationProperties(tf, saxonConfigurationProperties);
            XsltSaxonHelper.registerSaxonExtensionFunctions(tf, saxonExtensionFunctions);
        }

        if (factory != null) {
            log.debug("Using TransformerFactory {}", factory);
            xslt.setTransformerFactory(factory);
        }
        if (getResultHandlerFactory() != null) {
            xslt.setResultHandlerFactory(getResultHandlerFactory());
        }
        if (getErrorListener() != null) {
            xslt.errorListener(getErrorListener());
        }
        xslt.setFailOnNullBody(isFailOnNullBody());
        xslt.transformerCacheSize(getTransformerCacheSize());
        xslt.setUriResolver(getUriResolver());
        xslt.setEntityResolver(getEntityResolver());
        xslt.setAllowStAX(allowStAX);
        xslt.setDeleteOutputFile(isDeleteOutputFile());

        configureOutput(xslt, getOutput().name());

        // any additional transformer parameters then make a copy to avoid side-effects
        if (getParameters() != null) {
            Map<String, Object> copy = new HashMap<>(getParameters());
            xslt.setParameters(copy);
        }

        // must load resource first which sets a template and do a stylesheet compilation to catch errors early
        loadResource(getResourceUri(), xslt);

        return xslt;
    }

}
