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

import java.beans.PropertyChangeListener;
import java.util.Vector;

import org.apache.bsf.util.CodeBuffer;

/**
 * This is the view of a scripting engine assumed by the Bean Scripting Framework. This interface is used when an application decides to run some script under
 * application control. (This is the reverse of the more common situation, which is that of the scripting language calling into the application.)
 * <p>
 * When a scripting engine is first fired up, the initialize() method is called right after construction.
 * <p>
 * A scripting engine must provide two access points for applications to call into them: via function calls and via expression evaluation. It must also support
 * loading scripts.
 * <p>
 * A scripting engine is a property change listener and will be notified when any of the relevant properties of the manager change. (See BSFManager to see which
 * of its properties are bound.)
 */
public interface BSFEngine extends PropertyChangeListener {

    /**
     * This is used by an application to invoke an anonymous function. An anonymous function is a multi-line script which when evaluated will produce a value.
     * These are separated from expressions and scripts because the prior are spsed to be good 'ol expressions and scripts are not value returning. We allow
     * anonymous functions to have parameters as well for completeness.
     *
     * @param source     (context info) the source of this expression (e.g., filename)
     * @param lineNo     (context info) the line number in source for expr
     * @param columnNo   (context info) the column number in source for expr
     * @param funcBody   the multi-line, value returning script to evaluate
     * @param paramNames the names of the parameters above assumes
     * @param arguments  values of the above parameters
     *
     * @exception BSFException if anything goes wrong while doin' it.
     */
    Object apply(String source, int lineNo, int columnNo, Object funcBody, Vector paramNames, Vector arguments) throws BSFException;

    /**
     * This is used by an application to call into the scripting engine to make a function/method call. The "object" argument is the object whose method is to
     * be called, if that applies. For non-OO languages, this is typically ignored and should be given as null. For pretend-OO languages such as VB, this would
     * be the (String) name of the object. The arguments are given in the args array.
     *
     * @param object object on which to make the call
     * @param name   name of the method / procedure to call
     * @param args   the arguments to be given to the procedure
     *
     * @exception BSFException if anything goes wrong while eval'ing a BSFException is thrown. The reason indicates the problem.
     */
    Object call(Object object, String name, Object[] args) throws BSFException;

    /**
     * This is used by an application to compile an anonymous function. See comments in apply for more hdetails.
     *
     * @param source     (context info) the source of this expression (e.g., filename)
     * @param lineNo     (context info) the line number in source for expr
     * @param columnNo   (context info) the column number in source for expr
     * @param funcBody   the multi-line, value returning script to evaluate
     * @param paramNames the names of the parameters above assumes
     * @param arguments  values of the above parameters
     * @param cb         the CodeBuffer to compile into
     *
     * @exception BSFException if anything goes wrong while doin' it.
     */
    void compileApply(String source, int lineNo, int columnNo, Object funcBody, Vector paramNames, Vector arguments, CodeBuffer cb) throws BSFException;

    /**
     * This is used by an application to compile a value-returning expression. The expr may be string or some other type, depending on the language. The
     * generated code is dumped into the {@code CodeBuffer}.
     *
     * @param source   (context info) the source of this expression (e.g., filename)
     * @param lineNo   (context info) the line number in source for expr
     * @param columnNo (context info) the column number in source for expr
     * @param expr     the expression to compile
     * @param cb       the CodeBuffer to compile into
     *
     * @exception BSFException if anything goes wrong while compiling a BSFException is thrown. The reason indicates the problem.
     */
    void compileExpr(String source, int lineNo, int columnNo, Object expr, CodeBuffer cb) throws BSFException;

    /**
     * This is used by an application to compile some script. The script may be string or some other type, depending on the language. The generated code is
     * dumped into the {@code CodeBuffer}.
     *
     * @param source   (context info) the source of this script (e.g., filename)
     * @param lineNo   (context info) the line number in source for script
     * @param columnNo (context info) the column number in source for script
     * @param script   the script to compile
     * @param cb       the CodeBuffer to compile into
     *
     * @exception BSFException if anything goes wrong while compiling a BSFException is thrown. The reason indicates the problem.
     */
    void compileScript(String source, int lineNo, int columnNo, Object script, CodeBuffer cb) throws BSFException;

    /**
     * Declare a bean after the engine has been started. Declared beans are beans that are named and which the engine must make available to the scripts it runs
     * in the most first class way possible.
     *
     * @param bean the bean to declare
     *
     * @exception BSFException if the engine cannot do this operation
     */
    void declareBean(BSFDeclaredBean bean) throws BSFException;

    /**
     * This is used by an application to evaluate an expression. The expression may be string or some other type, depending on the language. (For example, for
     * BML it'll be an org.w3c.dom.Element object.)
     *
     * @param source   (context info) the source of this expression (e.g., filename)
     * @param lineNo   (context info) the line number in source for expr
     * @param columnNo (context info) the column number in source for expr
     * @param expr     the expression to evaluate
     *
     * @exception BSFException if anything goes wrong while eval'ing a BSFException is thrown. The reason indicates the problem.
     */
    Object eval(String source, int lineNo, int columnNo, Object expr) throws BSFException;

    /**
     * This is used by an application to execute some script. The expression may be string or some other type, depending on the language. Returns nothing but if
     * something goes wrong it excepts (of course).
     *
     * @param source   (context info) the source of this expression (e.g., filename)
     * @param lineNo   (context info) the line number in source for expr
     * @param columnNo (context info) the column number in source for expr
     * @param script   the script to execute
     *
     * @exception BSFException if anything goes wrong while exec'ing a BSFException is thrown. The reason indicates the problem.
     */
    void exec(String source, int lineNo, int columnNo, Object script) throws BSFException;

    /**
     * This is used by an application to execute some script, as though one were interacting with the language in an interactive session. The expression may be
     * string or some other type, depending on the language. Returns nothing but if something goes wrong it excepts (of course).
     *
     * @param source   (context info) the source of this expression (e.g., filename)
     * @param lineNo   (context info) the line number in source for expr
     * @param columnNo (context info) the column number in source for expr
     * @param script   the script to execute
     *
     * @exception BSFException if anything goes wrong while exec'ing a BSFException is thrown. The reason indicates the problem.
     */
    void iexec(String source, int lineNo, int columnNo, Object script) throws BSFException;

    /**
     * This method is used to initialize the engine right after construction. This method will be called before any calls to eval or call. At this time the
     * engine should capture the current values of interesting properties from the manager. In the future, any changes to those will be mirrored to me by the
     * manager via a property change event.
     *
     * @param mgr           The BSFManager that's hosting this engine.
     * @param lang          Language string which this engine is handling.
     * @param declaredBeans Vector of BSFDeclaredObject containing beans that should be declared into the language runtime at init time as best as possible.
     *
     * @exception BSFException if anything goes wrong while init'ing a BSFException is thrown. The reason indicates the problem.
     */
    void initialize(BSFManager mgr, String lang, Vector declaredBeans) throws BSFException;

    /**
     * Graceful termination
     */
    void terminate();

    /**
     * Undeclare a previously declared bean.
     *
     * @param bean the bean to undeclare
     *
     * @exception BSFException if the engine cannot do this operation
     */
    void undeclareBean(BSFDeclaredBean bean) throws BSFException;
}
