/*
 * 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.pipes;

import org.apache.commons.io.IOUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Execution bindings of a pipe, and all expression related
 */
public class PipeBindings {
    /**
     * interface mapping a javascript date
     */
    public interface JsDate {
        long getTime();
        int getTimezoneOffset();
    }

    private static final Logger log = LoggerFactory.getLogger(PipeBindings.class);

    public static final String NASHORNSCRIPTENGINE = "nashorn";
    
    public static final String NN_ADDITIONALBINDINGS = "additionalBindings";

    public static final String PN_ADDITIONALSCRIPTS = "additionalScripts";

    /**
     * add ${path.pipeName} binding allowing to retrieve pipeName's current resource path
     */
    public static final String PATH_BINDING = "path";

    /**
     * add ${name.pipeName} binding allowing to retrieve pipeName's current resource name
     */
    public static final String NAME_BINDING = "name";
    
    private static final Pattern INJECTED_SCRIPT = Pattern.compile("\\$\\{(([^\\{^\\}]*(\\{[0-9,]+\\})?)*)\\}");

    ScriptEngine engine;
    
    ScriptContext scriptContext = new SimpleScriptContext();

    Map<String, String> pathBindings = new HashMap<>();

    Map<String, String> nameBindings = new HashMap<>();

    Map<String, Resource> outputResources = new HashMap<>();

    String currentError;

    /**
     * public constructor, built from pipe's resource
     * @param resource pipe's configuration resource
     * @throws ScriptException in case scripts associated with the bindings are not assessable
     */
    public PipeBindings(Resource resource) throws ScriptException {
    	//Setup script engines
    	initializeScriptEngine();
    	
        //add path bindings where path.MyPipe will give MyPipe current resource path
        getBindings().put(PATH_BINDING, pathBindings);

        //add name bindings where name.MyPipe will give MyPipe current resource name
        getBindings().put(NAME_BINDING, nameBindings);

        //additional bindings (global variables to use in child pipes expressions)
        Resource additionalBindings = resource.getChild(NN_ADDITIONALBINDINGS);
        if (additionalBindings != null) {
            ValueMap bindings = additionalBindings.adaptTo(ValueMap.class);
            addBindings(bindings);
            for (String ignoredProperty : BasePipe.IGNORED_PROPERTIES){
                getBindings().remove(ignoredProperty);
            }
        }

        Resource scriptsResource = resource.getChild(PN_ADDITIONALSCRIPTS);
        if (scriptsResource != null) {
            String[] scripts = scriptsResource.adaptTo(String[].class);
            if (scripts != null) {
                for (String script : scripts){
                    addScript(resource.getResourceResolver(), script);
                }
            }
        }
    }

    /**
     * add a binding
     * @param name binding's name
     * @param value binding's value
     */
    public void addBinding(String name, Object value){
        log.debug("Adding binding {}={}", name, value);
        getBindings().put(name, value);
    }

    /**
     * adds additional bindings (global variables to use in child pipes expressions)
     * @param bindings key/values bindings to add to the existing bindings
     */
    public void addBindings(Map bindings) {
        log.info("Adding bindings {}", bindings);
        getBindings().putAll(bindings);
    }

    /**
     * add a script file to the engine
     * @param resolver resolver with which the file should be read
     * @param path path of the script file
     */
    public void addScript(ResourceResolver resolver, String path) {
        InputStream is = null;
        try {
            if (path.startsWith("http")) {
                try {
                    URL remoteScript = new URL(path);
                    is = remoteScript.openStream();
                } catch (Exception e) {
                    log.error("unable to retrieve remote script", e);
                }
            } else if (path.startsWith("/")) {
                Resource scriptResource = resolver.getResource(path);
                if (scriptResource != null) {
                    is = scriptResource.adaptTo(InputStream.class);
                }
            }
            if (is != null) {
                try {
                    engine.eval(new InputStreamReader(is), scriptContext);
                } catch (Exception e) {
                    log.error("Add script: unable to evaluate script {}", path, e);
                }
            }
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    /**
     * @param expr expression with or without ${} use
     * @return true if the expression is 'just' a plain string
     */
    public boolean isPlainString(String expr){
        return computeECMA5Expression(expr) == null;
    }

    /**
     * Doesn't look like nashorn likes template strings :-(
     * @param expr ECMA like expression <code>blah${'some' + 'ecma' + 'expression'}</code>
     * @return computed expression, null if the expression is a plain string
     */
    protected String computeECMA5Expression(String expr){
        Matcher matcher = INJECTED_SCRIPT.matcher(expr);
        if (INJECTED_SCRIPT.matcher(expr).find()) {
            StringBuilder expression = new StringBuilder();
            int start = 0;
            while (matcher.find()) {
                if (matcher.start() > start) {
                    if (expression.length() == 0) {
                        expression.append("'");
                    }
                    expression.append(expr.substring(start, matcher.start()));
                }
                if (expression.length() > 0) {
                    expression.append("' + ");
                }
                expression.append(matcher.group(1));
                start = matcher.end();
                if (start < expr.length()) {
                    expression.append(" + '");
                }
            }
            if (start < expr.length()) {
                expression.append(expr.substring(start) + "'");
            }
            return expression.toString();
        }
        return null;
    }

    /**
     * copy bindings
     * @param original original bindings to copy
     */
    public void copyBindings(PipeBindings original){
        getBindings().putAll(original.getBindings());
    }

    /**
     * evaluate a given expression
     * @param expr ecma like expression
     * @return object that is the result of the expression
     * @throws ScriptException in case the script fails, an exception is thrown (to let call code the opportunity to stop the execution)
     */
    protected Object evaluate(String expr) throws ScriptException {
        String computed = computeECMA5Expression(expr);
        if (computed != null){
            //computed is null in case expr is a simple string
            return engine.eval(computed, scriptContext);
        }
        return expr;
    }

    /**
     * return registered bindings
     * @return bindings
     */
    public Bindings getBindings() {
        return scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
    }
    
    /**
     * return Pipe <code>name</code>'s output binding
     * @param name name of the pipe
     * @return resource corresponding to that pipe output
     */
    public Resource getExecutedResource(String name) {
        return outputResources.get(name);
    }

    /**
     * Initialize the ScriptEngine.
     * In some contexts the nashorn engine cannot be obtained from thread's class loader. Do fallback to system classloader.
     * @throws ScriptException
     */
    private void initializeScriptEngine() throws ScriptException{
    	engine = new ScriptEngineManager().getEngineByName(PipeBindings.NASHORNSCRIPTENGINE);
    	if(engine == null){
        	//Fallback to system classloader
    		engine = new ScriptEngineManager(null).getEngineByName(PipeBindings.NASHORNSCRIPTENGINE);
    		//Check if nashorn can still not be instantiated
    		if(engine == null){
    			throw new ScriptException("Can not instantiate nashorn scriptengine. Check JVM version & capabilities.");
    		}
    	}
    	engine.setContext(scriptContext);
    }

    /**
     * Expression is a function of variables from execution context, that
     * we implement here as a String
     * @param expr ecma like expression
     * @return String that is the result of the expression
     * @throws ScriptException in case expression computing went wrong
     */
    public String instantiateExpression(String expr) throws ScriptException {
        return (String)evaluate(expr);
    }

    /**
     * Instantiate object from expression
     * @param expr ecma expression
     * @return instantiated object
     * @throws ScriptException in case object computing went wrong
     */
    public Object instantiateObject(String expr) throws ScriptException {
        Object result = evaluate(expr);
        if (result != null && ! result.getClass().getName().startsWith("java.lang.")) {
            //special case of the date in which case jdk.nashorn.api.scripting.ScriptObjectMirror will
            //be returned
            JsDate jsDate = ((Invocable) engine).getInterface(result, JsDate.class);
            if (jsDate != null ) {
                Date date = new Date(jsDate.getTime() + jsDate.getTimezoneOffset() * 60 * 1000);
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                return cal;
            }
        }
        return result;
    }

    /**
     * check if a given bindings is defined or not
     * @param name name of the binding
     * @return true if <code>name</code> is registered
     */
    public boolean isBindingDefined(String name){
        return getBindings().containsKey(name);
    }

    /**
     * Update current resource of a given pipe, and appropriate binding
     * @param pipe pipe we'll extract the output binding from
     * @param resource current resource in the pipe execution
     */
    public void updateBindings(Pipe pipe, Resource resource) {
        outputResources.put(pipe.getName(), resource);
        updateStaticBindings(pipe.getName(), resource);
        addBinding(pipe.getName(), pipe.getOutputBinding());
    }

    /**
     * Update all the static bindings related to a given resource
     * @param name name under which static bindings should be recorded
     * @param resource resource from which static bindings will be built
     */
    public void updateStaticBindings(String name, Resource resource){
        if (resource != null) {
            pathBindings.put(name, resource.getPath());
            nameBindings.put(name, resource.getName());
        }
    }

    /**
     * @return current error if any, and reset it
     */
    public String popCurrentError() {
        String returnValue = currentError;
        currentError = null;
        return returnValue;
    }

    /**
     * @param currentError error path to set
     */
    public void setCurrentError(String currentError) {
        this.currentError = currentError;
    }
}
