/*
 * 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.struts2.views.xslt;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;

import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * XSLTResult uses XSLT to transform an action object to XML.
 */
public class XSLTResult implements Result {

    private static final long serialVersionUID = 6424691441777176763L;

    /** Log instance for this result. */
    private static final Logger LOG = LogManager.getLogger(XSLTResult.class);

    /** 'stylesheetLocation' parameter.  Points to the xsl. */
    public static final String DEFAULT_PARAM = "stylesheetLocation";

    /**
     * Cache of all templates.
     */
    private static final Map<String, Templates> templatesCache;

    static {
        templatesCache = new HashMap<>();
    }

    // Configurable Parameters

    /** Determines whether or not the result should allow caching. */
    protected boolean noCache;

    /** Indicates the location of the xsl template. */
    private String stylesheetLocation;

    /** Indicates the property name patterns which should be exposed to the xml. */
    private String matchingPattern;

    /** Indicates the property name patterns which should be excluded from the xml. */
    private String excludingPattern;

    /** Indicates the ognl expression representing the bean which is to be exposed as xml. */
    private String exposedValue;

    /** Indicates the status to return in the response */
    private int status = 200;

    private String encoding = "UTF-8";

    private boolean parse;
    private AdapterFactory adapterFactory;

    public XSLTResult() {
    }

    public XSLTResult(String stylesheetLocation) {
        this();
        setStylesheetLocation(stylesheetLocation);
    }
    
    @Inject(StrutsConstants.STRUTS_XSLT_NOCACHE)
    public void setNoCache(String xsltNoCache) {
        this.noCache = BooleanUtils.toBoolean(xsltNoCache);
    }

    public void setStylesheetLocation(String location) {
        this.stylesheetLocation = location;
    }

    public String getStylesheetLocation() {
        return stylesheetLocation;
    }

    public String getExposedValue() {
        return exposedValue;
    }

    public void setExposedValue(String exposedValue) {
        this.exposedValue = exposedValue;
    }

    public String getStatus() {
        return String.valueOf(status);
    }

    public void setStatus(String status) {
        try {
            this.status = Integer.valueOf(status);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Status value not number " + e.getMessage(), e);
        }
    }

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    /**
     * @param parse if true, parse the stylesheet location for OGNL expressions.
     */
    public void setParse(boolean parse) {
        this.parse = parse;
    }

    public void execute(ActionInvocation invocation) throws Exception {
        if (invocation == null) {
            throw new IllegalArgumentException("Invocation cannot be null!");
        }

        long startTime = System.currentTimeMillis();
        String location = getStylesheetLocation();

        if (location == null) {
            throw new IllegalArgumentException("Parameter 'stylesheetLocation' cannot be null!");
        }

        if (parse) {
            ValueStack stack = invocation.getStack();
            location = TextParseUtil.translateVariables(location, stack);
        }

        try {
            HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
            response.setStatus(status);
            response.setCharacterEncoding(encoding);
            PrintWriter writer = response.getWriter();

            // Create a transformer for the stylesheet.
            Templates templates = null;
            Transformer transformer;
            if (location != null) {
                templates = getTemplates(location);
                transformer = templates.newTransformer();
            } else {
                transformer = TransformerFactory.newInstance().newTransformer();
            }

            transformer.setURIResolver(getURIResolver());
            transformer.setErrorListener(buildErrorListener());

            String mimeType;
            if (templates == null) {
                mimeType = "text/xml"; // no stylesheet, raw xml
            } else {
                mimeType = templates.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
            }

            if (mimeType == null) {
                // guess (this is a servlet, so text/html might be the best guess)
                mimeType = "text/html";
            }

            response.setContentType(mimeType);

            Object result = invocation.getAction();
            if (exposedValue != null) {
                ValueStack stack = invocation.getStack();
                result = stack.findValue(exposedValue);
            }

            Source xmlSource = getDOMSourceForStack(result);

            // Transform the source XML to System.out.
            LOG.debug("xmlSource = {}", xmlSource);
            transformer.transform(xmlSource, new StreamResult(writer));

            writer.flush(); // ...and flush...

            LOG.debug("Time: {}ms", (System.currentTimeMillis() - startTime));

        } catch (Exception e) {
            LOG.error("Unable to render XSLT Template, '{}'", location, e);
            throw e;
        }
    }

    protected ErrorListener buildErrorListener() {
        return new ErrorListener() {

            public void error(TransformerException exception) throws TransformerException {
                throw new StrutsException("Error transforming result", exception);
            }

            public void fatalError(TransformerException exception) throws TransformerException {
                throw new StrutsException("Fatal error transforming result", exception);
            }

            public void warning(TransformerException exception) throws TransformerException {
                LOG.warn(exception.getMessage(), exception);
            }

        };
    }

    protected AdapterFactory getAdapterFactory() {
        if (adapterFactory == null) {
            adapterFactory = new AdapterFactory();
        }
        return adapterFactory;
    }

    protected void setAdapterFactory(AdapterFactory adapterFactory) {
        this.adapterFactory = adapterFactory;
    }

    /**
     * @return the URI Resolver to be called by the processor when it encounters an xsl:include, xsl:import, or document()
     * function. The default is an instance of ServletURIResolver, which operates relative to the servlet context.
     */
    protected URIResolver getURIResolver() {
        return new ServletURIResolver(ServletActionContext.getServletContext());
    }

    protected Templates getTemplates(final String path) throws TransformerException, IOException {
        if (path == null)
            throw new TransformerException("Stylesheet path is null");

        Templates templates = templatesCache.get(path);

        if (noCache || (templates == null)) {
            synchronized (templatesCache) {
                URL resource = ServletActionContext.getServletContext().getResource(path);

                if (resource == null) {
                    throw new TransformerException("Stylesheet " + path + " not found in resources.");
                }

                LOG.debug("Preparing XSLT stylesheet templates: {}", path);

                TransformerFactory factory = TransformerFactory.newInstance();
                factory.setURIResolver(getURIResolver());
                factory.setErrorListener(buildErrorListener());
                templates = factory.newTemplates(new StreamSource(resource.openStream()));
                templatesCache.put(path, templates);
            }
        }

        return templates;
    }

    protected Source getDOMSourceForStack(Object value) throws IllegalAccessException, InstantiationException {
        return new DOMSource(getAdapterFactory().adaptDocument("result", value) );
    }
}
