/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed 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.codehaus.groovy.bsf;

import groovy.lang.Closure;
import groovy.lang.GroovyShell;
import org.apache.bsf.BSFDeclaredBean;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.apache.bsf.util.BSFEngineImpl;
import org.apache.bsf.util.BSFFunctions;
import org.codehaus.groovy.runtime.InvokerHelper;

import java.util.Vector;

/**
 * A BSF Engine for the <a href="http://groovy.codehaus.org/">Groovy</a>
 * scripting language.
 * <p/>
 * It's derived from the Jython / JPython engine
 *
 * @author James Strachan
 */
public class GroovyEngine extends BSFEngineImpl {
    protected GroovyShell shell;

    /*
     * Convert a non java class name to a java classname
     * This is used to convert a script name to a name
     * that can be used as a classname with the script is
     * loaded in GroovyClassloader#load()
     * The method simply replaces any invalid characters
     * with "_".
     */
    private String convertToValidJavaClassname(String inName) {
        if (inName == null || inName.equals("")) {
            return "_";
        }
        StringBuffer output = new StringBuffer(inName.length());
        boolean firstChar = true;
        for (int i = 0; i < inName.length(); ++i) {
            char ch = inName.charAt(i);
            if (firstChar && !Character.isJavaIdentifierStart(ch)) {
                ch = '_';
            } else if (!firstChar
                    && !(Character.isJavaIdentifierPart(ch) || ch == '.')) {
                ch = '_';
            }
            firstChar = (ch == '.');
            output.append(ch);
        }
        return output.toString();
    }

    /**
     * Allow an anonymous function to be declared and invoked
     */
    public Object apply(String source, int lineNo, int columnNo, Object funcBody, Vector paramNames,
                        Vector arguments) throws BSFException {
        Object object = eval(source, lineNo, columnNo, funcBody);
        if (object instanceof Closure) {
            // lets call the function
            Closure closure = (Closure) object;
            return closure.call(arguments.toArray());
        }
        return object;
    }

    /**
     * Call the named method of the given object.
     */
    public Object call(Object object, String method, Object[] args) throws BSFException {
        return InvokerHelper.invokeMethod(object, method, args);
    }

    /**
     * Evaluate an expression.
     */
    public Object eval(String source, int lineNo, int columnNo, Object script) throws BSFException {
        try {
            source = convertToValidJavaClassname(source);
            return getEvalShell().evaluate(script.toString(), source);
        } catch (Exception e) {
            throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "exception from Groovy: " + e, e);
        }
    }

    /**
     * Execute a script.
     */
    public void exec(String source, int lineNo, int columnNo, Object script) throws BSFException {
        try {
            // use evaluate to pass in the BSF variables
            source = convertToValidJavaClassname(source);
            getEvalShell().evaluate(script.toString(), source);
        } catch (Exception e) {
            throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "exception from Groovy: " + e, e);
        }
    }

    /**
     * Initialize the engine.
     */
    public void initialize(BSFManager mgr, String lang, Vector declaredBeans) throws BSFException {
        super.initialize(mgr, lang, declaredBeans);

        // create a shell
        shell = new GroovyShell(mgr.getClassLoader());

        // register the mgr with object name "bsf"
        shell.setVariable("bsf", new BSFFunctions(mgr, this));

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

    /**
     * Declare a bean
     */
    public void declareBean(BSFDeclaredBean bean) throws BSFException {
        shell.setVariable(bean.name, bean.bean);
    }

    /**
     * Undeclare a previously declared bean.
     */
    public void undeclareBean(BSFDeclaredBean bean) throws BSFException {
        shell.setVariable(bean.name, null);
    }

    /**
     * @return a newly created GroovyShell using the same variable scope but a new class loader
     */
    protected GroovyShell getEvalShell() {
        return new GroovyShell(shell);
    }
}
