/*******************************************************************************
 * 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.ofbiz.base.util;

/*
 * Based on code that started with this header/license:
        This file is associated with the BeanShell Java Scripting language
        distribution (http://www.beanshell.org/).

        This file is hereby placed into the public domain...  You may copy,
        modify, and redistribute it without restriction.

 */

import java.io.StringReader;
import java.util.Vector;

import bsh.EvalError;
import bsh.Interpreter;
import bsh.Interpreter.ParsedScript;
import bsh.InterpreterError;
import bsh.TargetError;

import org.apache.bsf.BSFDeclaredBean;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.apache.bsf.util.BSFEngineImpl;

import org.ofbiz.base.util.cache.Cache;
import org.ofbiz.base.util.cache.UtilCache;

/**
 * This is the BeanShell adapter for IBM's Bean Scripting Famework.
 * It is an implementation of the BSFEngine class, allowing BSF aware
 * applications to use BeanShell as a scripting language.
 * <p>
 *
 * I believe this implementation is complete (with some hesitation about the
 * the usefullness of the compileXXX() style methods - provided by the base
 * utility class).
 *
 */
public class OfbizBshBsfEngine extends BSFEngineImpl {

    public static final String module = OfbizBshBsfEngine.class.getName();

    protected Interpreter interpreter;
    protected boolean installedApplyMethod;

    private static final Cache<String, ParsedScript> parsedScripts = UtilCache.createUtilCache("script.BshBsfParsedCache", 0, 0, false);

    @SuppressWarnings("unchecked")
    @Override
    public void initialize(BSFManager mgr, String lang, Vector declaredBeans) throws BSFException {
        super.initialize(mgr, lang, declaredBeans);

        interpreter = BshUtil.getMasterInterpreter(null);

        // declare the bsf manager for callbacks, etc.
        try {
            interpreter.set("bsf", mgr);
        } catch (EvalError e) {
            throw new BSFException("bsh internal error: "+e.toString());
        }

        for (int i=0; i<declaredBeans.size(); i++) {
            BSFDeclaredBean bean = (BSFDeclaredBean)declaredBeans.get(i);
            declareBean(bean);
        }
    }

    public void setDebug(boolean debug) {
        Interpreter.DEBUG=debug;
    }

    /**
     * Invoke method name on the specified bsh scripted object.
     * The object may be null to indicate the global namespace of the
     * interpreter.
     * @param object may be null for the global namespace.
     */
    public Object call(Object object, String name, Object[] args) throws BSFException {
        if (object == null) {
            try {
                object = interpreter.get("global");
            } catch (EvalError e) {
                throw new BSFException("bsh internal error: "+e.toString());
            }
        }

        if (object instanceof bsh.This) {
            try {
                return ((bsh.This)object).invokeMethod(name, args);
            } catch (InterpreterError e) {
                throw new BSFException("BeanShell interpreter internal error: "+e);
            } catch (TargetError e2) {
                throw new BSFException("The application script threw an exception: " + e2.getTarget());
            } catch (EvalError e3) {
                throw new BSFException("BeanShell script error: "+e3);
            }
        } else {
            throw new BSFException("Cannot invoke method: " + name +
            ". Object: "+object +" is not a BeanShell scripted object.");
        }
    }


    /**
     * A helper BeanShell method that implements the anonymous method apply
     * proposed by BSF.  Note that the script below could use the standard
     * bsh eval() method to set the variables and apply the text, however
     * then I'd have to escape quotes, etc.
     */
    final static String bsfApplyMethod =
    "_bsfApply(_bsfNames, _bsfArgs, _bsfText) {"
    +"for (i=0;i<_bsfNames.length;i++)"
    +"this.namespace.setVariable(_bsfNames[i], _bsfArgs[i]);"
    +"return this.interpreter.eval(_bsfText, this.namespace);"
    +"}";

    /**
     * This is an implementation of the BSF apply() method.
     * It executes the funcBody text in an "anonymous" method call with
     * arguments.
     */
    @SuppressWarnings("unchecked")
    @Override
    public Object apply(String source, int lineNo, int columnNo, Object funcBody, Vector namesVec, Vector argsVec) throws BSFException {
        if (namesVec.size() != argsVec.size()) throw new BSFException("number of params/names mismatch");
        if (!(funcBody instanceof String)) throw new BSFException("apply: function body must be a string");

        String [] names = new String [ namesVec.size() ];
        namesVec.copyInto(names);
        Object [] args = new String [ argsVec.size() ];
        argsVec.copyInto(args);

        try {
            if (!installedApplyMethod) {
                interpreter.eval(bsfApplyMethod);
                installedApplyMethod = true;
            }

            bsh.This global = (bsh.This)interpreter.get("global");
            return global.invokeMethod("_bsfApply", new Object [] { names, args, (String)funcBody });

        } catch (InterpreterError e) {
            throw new BSFException("BeanShell interpreter internal error: " + e + sourceInfo(source,lineNo,columnNo));
        } catch (TargetError e2) {
            throw new BSFException("The application script threw an exception: " + e2.getTarget() + sourceInfo(source,lineNo,columnNo));
        } catch (EvalError e3) {
            throw new BSFException("BeanShell script error: " + e3 + sourceInfo(source,lineNo,columnNo));
        }
    }

    public Object eval(String source, int lineNo, int columnNo, Object expr) throws BSFException {
        if (!(expr instanceof String)) throw new BSFException("BeanShell expression must be a string");

        try {
            //return interpreter.eval(((String) expr));

            Interpreter.ParsedScript script = null;

            if (UtilValidate.isNotEmpty(source)) {
                script = parsedScripts.get(source);
                if (script == null) {
                    script = interpreter.parseScript(source, new StringReader((String) expr));
                    Debug.logVerbose("Caching BSH script at: " + source, module);
                    script = parsedScripts.putIfAbsentAndGet(source, script);
                }
            } else {
                script = interpreter.parseScript(source, new StringReader((String) expr));
            }

            return interpreter.evalParsedScript(script);
        } catch (InterpreterError e) {
            throw new BSFException("BeanShell interpreter internal error: "+ e + sourceInfo(source,lineNo,columnNo));
        } catch (TargetError e2) {
            Debug.logError(e2, "Error thrown in BeanShell script called through BSF at: " + sourceInfo(source,lineNo,columnNo), module);
            //Debug.logError(e2.getTarget(), module);
            throw new BSFException("The application script threw an exception: " + e2 + " " + sourceInfo(source,lineNo,columnNo));
        } catch (EvalError e3) {
            throw new BSFException("BeanShell script error: " + e3 + sourceInfo(source,lineNo,columnNo));
        }
    }


    @Override
    public void exec(String source, int lineNo, int columnNo, Object script) throws BSFException {
        eval(source, lineNo, columnNo, script);
    }


/*
        public void compileApply (String source, int lineNo, int columnNo,
                Object funcBody, Vector paramNames, Vector arguments, CodeBuffer cb)
                throws BSFException;

        public void compileExpr (String source, int lineNo, int columnNo,
                Object expr, CodeBuffer cb) throws BSFException;

        public void compileScript (String source, int    lineNo,    int columnNo,
                Object script, CodeBuffer cb) throws BSFException;
 */

    @Override
    public void declareBean(BSFDeclaredBean bean) throws BSFException {
        try {
            interpreter.set(bean.name, bean.bean);
        } catch (EvalError e) {
            throw new BSFException("error declaring bean: " + bean.name + " : " + e.toString());
        }
    }

    @Override
    public void undeclareBean(BSFDeclaredBean bean) throws BSFException {
        try {
            interpreter.unset(bean.name);
        } catch (EvalError e) {
            throw new BSFException("bsh internal error: " + e.toString());
        }
    }

    @Override
    public void terminate() { }

    private String sourceInfo(String source, int lineNo, int columnNo) {
        return "BSF info: " + source + " at line: " + lineNo +" column: " + columnNo;
    }
}
