/*
 * 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.sling.scripting.java.impl;

import static org.apache.sling.api.scripting.SlingBindings.SLING;

import java.io.IOException;
import java.io.Reader;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingIOException;
import org.apache.sling.api.SlingServletException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScript;
import org.apache.sling.api.scripting.SlingScriptConstants;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.commons.compiler.JavaCompiler;
import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Java engine
 *
 */
@Component(metatype=true, label="%javahandler.name", description="%javahandler.description")
@Service(value={javax.script.ScriptEngineFactory.class, ResourceChangeListener.class})
@Properties({
    @Property(name="service.vendor", value="The Apache Software Foundation"),
    @Property(name="service.description", value="Java Servlet Script Handler"),
    @Property(name=JavaScriptEngineFactory.PROPERTY_COMPILER_SOURCE_V_M, value=JavaScriptEngineFactory.VERSION_AUTO),
    @Property(name=JavaScriptEngineFactory.PROPERTY_COMPILER_TARGET_V_M, value=JavaScriptEngineFactory.VERSION_AUTO),
    @Property(name=JavaScriptEngineFactory.PROPERTY_CLASSDEBUGINFO, boolValue=true),
    @Property(name=JavaScriptEngineFactory.PROPERTY_ENCODING, value="UTF-8"),
    @Property(name = ResourceChangeListener.CHANGES, value = {"CHANGED", "REMOVED"}),
    @Property(name = ResourceChangeListener.PATHS, value = {"."}, propertyPrivate = true)
})
public class JavaScriptEngineFactory
    extends AbstractScriptEngineFactory
    implements ResourceChangeListener, ExternalResourceChangeListener {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public static final String PROPERTY_COMPILER_SOURCE_V_M = "java.compilerSourceVM";

    public static final String PROPERTY_COMPILER_TARGET_V_M = "java.compilerTargetVM";

    public static final String PROPERTY_CLASSDEBUGINFO = "java.classdebuginfo";

    public static final String PROPERTY_ENCODING = "java.javaEncoding";

    public static final String VERSION_AUTO = "auto";

    @Reference
    private JavaCompiler javaCompiler;

    @Reference(target="(name=org.apache.sling)")
    private ServletContext slingServletContext;

    private SlingIOProvider ioProvider;

    private JavaServletContext javaServletContext;

    private ServletConfig servletConfig;

    public static final String SCRIPT_TYPE = "java";

    /**
     * Constructor
     */
    public JavaScriptEngineFactory() {
        setExtensions(SCRIPT_TYPE);
    }

    /**
     * @see javax.script.ScriptEngineFactory#getScriptEngine()
     */
    @Override
    public ScriptEngine getScriptEngine() {
        return new JavaScriptEngine(this);
    }

    /**
     * @see javax.script.ScriptEngineFactory#getLanguageName()
     */
    @Override
    public String getLanguageName() {
        return "Java Servlet Compiler";
    }

    /**
     * @see javax.script.ScriptEngineFactory#getLanguageVersion()
     */
    @Override
    public String getLanguageVersion() {
        return "1.5";
    }

    /**
     * @see javax.script.ScriptEngineFactory#getParameter(String)
     */
    @Override
    public Object getParameter(String name) {
        if ("THREADING".equals(name)) {
            return "STATELESS";
        }

        return super.getParameter(name);
    }

    /**
     * Activate this engine
     *
     * @param config Configuration properties
     */
    @Activate
    protected void activate(final Map<String, Object> config) {
        final CompilerOptions opts = CompilerOptions.createOptions(new Hashtable<>(config));
        this.ioProvider = new SlingIOProvider(this.javaCompiler, opts);
        this.javaServletContext = new JavaServletContext(ioProvider,
            slingServletContext);

        this.servletConfig = new JavaServletConfig(javaServletContext, config);

        logger.info("Activating Apache Sling Script Engine for Java with options {}", opts);
    }

    /**
     * Deactivate this engine
     */
    @Deactivate
    protected void deactivate() {
        if ( this.ioProvider != null ) {
            this.ioProvider.destroy();
            this.ioProvider = null;
        }
        javaServletContext = null;
        servletConfig = null;
        logger.info("Deactivating Apache Sling Script Engine for Java");
    }

    /**
     * Call the servlet.
     * @param bindings The bindings for the script invocation
     * @param scriptHelper The script helper.
     * @param context The script context.
     * @throws SlingServletException
     * @throws SlingIOException
     */
    private void callServlet(final Bindings bindings,
                             final SlingScriptHelper scriptHelper,
                             final ScriptContext context) {
        // create a SlingBindings object
        final SlingBindings slingBindings = new SlingBindings();
        slingBindings.putAll(bindings);

        ResourceResolver resolver = (ResourceResolver) context.getAttribute(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER,
                SlingScriptConstants.SLING_SCOPE);
        if ( resolver == null ) {
            resolver = scriptHelper.getScript().getScriptResource().getResourceResolver();
        }
        ioProvider.setRequestResourceResolver(resolver);

        final SlingHttpServletRequest request = slingBindings.getRequest();
        final Object oldValue = request.getAttribute(SlingBindings.class.getName());
        try {
            final ServletWrapper servlet = getWrapperAdapter(scriptHelper);

            request.setAttribute(SlingBindings.class.getName(), slingBindings);
            servlet.service(request, slingBindings.getResponse());
        } catch (SlingException se) {
            // rethrow as is
            throw se;
        } catch (IOException ioe) {
            throw new SlingIOException(ioe);
        } catch (ServletException se) {
            throw new SlingServletException(se);
        } catch (Exception ex) {
            throw new SlingException(null, ex);
        } finally {
            request.setAttribute(SlingBindings.class.getName(), oldValue);
            ioProvider.resetRequestResourceResolver();
        }
    }

    private ServletWrapper getWrapperAdapter(final SlingScriptHelper scriptHelper)
    throws SlingException {

        SlingScript script = scriptHelper.getScript();
        final String scriptName = script.getScriptResource().getPath();
        ServletWrapper wrapper = this.ioProvider.getServletCache().getWrapper(scriptName);
        if (wrapper != null) {
            return wrapper;
        }

        wrapper = new ServletWrapper(servletConfig,
                                     ioProvider,
                                     scriptName,
                                     scriptHelper);
        wrapper = this.ioProvider.getServletCache().addWrapper(scriptName, wrapper);

        return wrapper;
    }

    @Override
	public void onChange(List<ResourceChange> resourceChange) {
		for(ResourceChange change : resourceChange){
			ChangeType topic = change.getType();
			if (topic.equals(ChangeType.CHANGED)) {
				this.handleModification(change.getPath(), false);
			} else if (topic.equals(ChangeType.REMOVED)){
				this.handleModification(change.getPath(), true);
			}
		}
	}

    private void handleModification(final String scriptName, final boolean remove) {
        this.ioProvider.getServletCache().removeWrapper(scriptName, remove);
    }

    private static class JavaScriptEngine extends AbstractSlingScriptEngine {

        JavaScriptEngine(JavaScriptEngineFactory factory) {
            super(factory);
        }

        /**
         * @see javax.script.ScriptEngine#eval(java.io.Reader, javax.script.ScriptContext)
         */
        @Override
        public Object eval(Reader script, ScriptContext context)
        throws ScriptException {
            final Bindings props = context.getBindings(ScriptContext.ENGINE_SCOPE);
            final SlingScriptHelper scriptHelper = (SlingScriptHelper) props.get(SLING);
            if (scriptHelper != null) {
                ((JavaScriptEngineFactory)this.getFactory()).callServlet(props, scriptHelper, context);
            }
            return null;
        }
    }
}
