package org.apache.velocity.runtime;

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

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.Template;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.log.Log;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.runtime.resource.ContentResource;
import org.apache.velocity.util.introspection.Introspector;
import org.apache.velocity.util.introspection.Uberspect;


/**
 * Interface for internal runtime services that are needed by the
 * various components w/in Velocity.  This was taken from the old
 * Runtime singleton, and anything not necessary was removed.
 *
 *  Currently implemented by RuntimeInstance.
 *
 * @author <a href="mailto:geirm@optonline.net">Geir Magusson Jr.</a>
 * @version $Id$
 */
public interface RuntimeServices extends RuntimeLogger
{

   /**
     * This is the primary initialization method in the Velocity
     * Runtime. The systems that are setup/initialized here are
     * as follows:
     *
     * <ul>
     *   <li>Logging System</li>
     *   <li>ResourceManager</li>
     *   <li>Parser Pool</li>
     *   <li>Global Cache</li>
     *   <li>Static Content Include System</li>
     *   <li>Velocimacro System</li>
     * </ul>
     * @throws Exception
     */
    public void init() throws Exception;

    /**
     * Allows an external system to set a property in
     * the Velocity Runtime.
     *
     * @param key property key
     * @param value property value
     */
    public  void setProperty(String key, Object value);

    /**
     * Allow an external system to set an ExtendedProperties
     * object to use. This is useful where the external
     * system also uses the ExtendedProperties class and
     * the velocity configuration is a subset of
     * parent application's configuration. This is
     * the case with Turbine.
     *
     * @param configuration
     */
    public void setConfiguration( ExtendedProperties configuration);

    /**
     * Add a property to the configuration. If it already
     * exists then the value stated here will be added
     * to the configuration entry. For example, if
     *
     * resource.loader = file
     *
     * is already present in the configuration and you
     *
     * addProperty("resource.loader", "classpath")
     *
     * Then you will end up with a Vector like the
     * following:
     *
     * ["file", "classpath"]
     *
     * @param key
     * @param value
     */
    public void addProperty(String key, Object value);

    /**
     * Clear the values pertaining to a particular
     * property.
     *
     * @param key of property to clear
     */
    public void clearProperty(String key);

    /**
     *  Allows an external caller to get a property.  The calling
     *  routine is required to know the type, as this routine
     *  will return an Object, as that is what properties can be.
     *
     *  @param key property to return
     * @return The value.
     */
    public  Object getProperty( String key );

    /**
     * Initialize the Velocity Runtime with a Properties
     * object.
     *
     * @param p
     * @throws Exception
     */
    public void init(Properties p) throws Exception;

    /**
     * Initialize the Velocity Runtime with the name of
     * ExtendedProperties object.
     *
     * @param configurationFile
     * @throws Exception
     */
    public void init(String configurationFile) throws Exception;

    /**
     * Wraps the String in a StringReader and passes it off to
     * {@link #parse(Reader,String)}.
     * @since 1.6
     */
    public SimpleNode parse(String string, String templateName)
        throws ParseException;

    /**
     * Parse the input and return the root of
     * AST node structure.
     * <br><br>
     *  In the event that it runs out of parsers in the
     *  pool, it will create and let them be GC'd
     *  dynamically, logging that it has to do that.  This
     *  is considered an exceptional condition.  It is
     *  expected that the user will set the
     *  PARSER_POOL_SIZE property appropriately for their
     *  application.  We will revisit this.
     *
     * @param reader inputstream retrieved by a resource loader
     * @param templateName name of the template being parsed
     * @return The AST representing the template.
     * @throws ParseException
     */
    public  SimpleNode parse( Reader reader, String templateName )
        throws ParseException;

    /**
     *  Parse the input and return the root of the AST node structure.
     *
     * @param reader inputstream retrieved by a resource loader
     * @param templateName name of the template being parsed
     * @param dumpNamespace flag to dump the Velocimacro namespace for this template
     * @return The AST representing the template.
     * @throws ParseException
     */
    public SimpleNode parse( Reader reader, String templateName, boolean dumpNamespace )
        throws ParseException;

    /**
     * Renders the input string using the context into the output writer.
     * To be used when a template is dynamically constructed, or want to use
     * Velocity as a token replacer.
     *
     * @param context context to use in rendering input string
     * @param out  Writer in which to render the output
     * @param logTag  string to be used as the template name for log
     *                messages in case of error
     * @param instring input string containing the VTL to be rendered
     *
     * @return true if successful, false otherwise.  If false, see
     *              Velocity runtime log
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     * @since Velocity 1.6
     */
    public boolean evaluate(Context context, Writer out,
                            String logTag, String instring) throws IOException;

    /**
     * Renders the input reader using the context into the output writer.
     * To be used when a template is dynamically constructed, or want to
     * use Velocity as a token replacer.
     *
     * @param context context to use in rendering input string
     * @param writer  Writer in which to render the output
     * @param logTag  string to be used as the template name for log messages
     *                in case of error
     * @param reader Reader containing the VTL to be rendered
     *
     * @return true if successful, false otherwise.  If false, see
     *              Velocity runtime log
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While reading from the reader or rendering to the writer,
     *                     an I/O problem occured.
     * @since Velocity 1.6
     */
    public boolean evaluate(Context context, Writer writer,
                            String logTag, Reader reader) throws IOException;

    /**
     * Invokes a currently registered Velocimacro with the params provided
     * and places the rendered stream into the writer.
     * <br>
     * Note : currently only accepts args to the VM if they are in the context.
     *
     * @param vmName name of Velocimacro to call
     * @param logTag string to be used for template name in case of error. if null,
     *               the vmName will be used
     * @param params keys for args used to invoke Velocimacro, in java format
     *               rather than VTL (eg  "foo" or "bar" rather than "$foo" or "$bar")
     * @param context Context object containing data/objects used for rendering.
     * @param writer  Writer for output stream
     * @return true if Velocimacro exists and successfully invoked, false otherwise.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     * @since 1.6
     */
    public boolean invokeVelocimacro(final String vmName, String logTag,
                                     String[] params, final Context context,
                                     final Writer writer) throws IOException;

    /**
     * Returns a <code>Template</code> from the resource manager.
     * This method assumes that the character encoding of the
     * template is set by the <code>input.encoding</code>
     * property.  The default is "ISO-8859-1"
     *
     * @param name The file name of the desired template.
     * @return     The template.
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException if template cannot be parsed due
     *          to syntax (or other) error.
     * @throws Exception if an error occurs in template initialization
     */
    public Template getTemplate(String name)
        throws ResourceNotFoundException, ParseErrorException, Exception;

    /**
     * Returns a <code>Template</code> from the resource manager
     *
     * @param name The  name of the desired template.
     * @param encoding Character encoding of the template
     * @return     The template.
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException if template cannot be parsed due
     *          to syntax (or other) error.
     * @throws Exception if an error occurs in template initialization
     */
    public Template getTemplate(String name, String  encoding)
        throws ResourceNotFoundException, ParseErrorException, Exception;

    /**
     * Returns a static content resource from the
     * resource manager.  Uses the current value
     * if INPUT_ENCODING as the character encoding.
     *
     * @param name Name of content resource to get
     * @return parsed ContentResource object ready for use
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException
     * @throws Exception
     */
    public ContentResource getContent(String name)
        throws ResourceNotFoundException, ParseErrorException, Exception;

    /**
     * Returns a static content resource from the
     * resource manager.
     *
     * @param name Name of content resource to get
     * @param encoding Character encoding to use
     * @return parsed ContentResource object ready for use
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException
     * @throws Exception
     */
    public ContentResource getContent( String name, String encoding )
        throws ResourceNotFoundException, ParseErrorException, Exception;

    /**
     *  Determines is a template exists, and returns name of the loader that
     *  provides it.  This is a slightly less hokey way to support
     *  the Velocity.templateExists() utility method, which was broken
     *  when per-template encoding was introduced.  We can revisit this.
     *
     *  @param resourceName Name of template or content resource
     *  @return class name of loader than can provide it
     */
    public String getLoaderNameForResource( String resourceName );

    /**
     * String property accessor method with default to hide the
     * configuration implementation.
     *
     * @param key property key
     * @param defaultValue  default value to return if key not
     *               found in resource manager.
     * @return String  value of key or default
     */
    public String getString( String key, String defaultValue);

    /**
     * Returns the appropriate VelocimacroProxy object if strVMname
     * is a valid current Velocimacro.
     *
     * @param vmName  Name of velocimacro requested
     * @param templateName Name of the namespace.
     * @return VelocimacroProxy
     */
    public Directive getVelocimacro( String vmName, String templateName  );
    
    /**
     * Returns the appropriate VelocimacroProxy object if strVMname
     * is a valid current Velocimacro.
     *
     * @param vmName  Name of velocimacro requested
     * @param templateName Name of the namespace.
     * @param renderingTemplate Name of the template we are currently rendering. This
     *    information is needed when VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL setting is true
     *    and template contains a macro with the same name as the global macro library.
     * 
     * @since Velocity 1.6
     * 
     * @return VelocimacroProxy
     */
    public Directive getVelocimacro( String vmName, String templateName, String renderingTemplate  );

   /**
     * Adds a new Velocimacro. Usually called by Macro only while parsing.
     *
     * @param name  Name of velocimacro
     * @param macro  String form of macro body
     * @param argArray  Array of strings, containing the
     *                         #macro() arguments.  the 0th is the name.
     * @param sourceTemplate
     * 
     * @deprecated Use addVelocimacro(String, Node, String[], String) instead
     *                   
     * @return boolean  True if added, false if rejected for some
     *                  reason (either parameters or permission settings)
     */
    public boolean addVelocimacro( String name,
                                          String macro,
                                          String argArray[],
                                          String sourceTemplate );

    /**
     * Adds a new Velocimacro. Usually called by Macro only while parsing.
     *
     * @param name  Name of velocimacro
     * @param macro  root AST node of the parsed macro
     * @param argArray  Array of strings, containing the
     *                         #macro() arguments.  the 0th is the name.
     * @param sourceTemplate
     * 
     * @since Velocity 1.6
     *                   
     * @return boolean  True if added, false if rejected for some
     *                  reason (either parameters or permission settings)
     */
    public boolean addVelocimacro( String name,
                                          Node macro,
                                          String argArray[],
                                          String sourceTemplate );
                                          
                                          
    /**
     *  Checks to see if a VM exists
     *
     * @param vmName  Name of velocimacro
     * @param templateName
     * @return boolean  True if VM by that name exists, false if not
     */
    public boolean isVelocimacro( String vmName, String templateName );

    /**
     *  tells the vmFactory to dump the specified namespace.  This is to support
     *  clearing the VM list when in inline-VM-local-scope mode
     * @param namespace
     * @return True if the Namespace was dumped.
     */
    public boolean dumpVMNamespace( String namespace );

    /**
     * String property accessor method to hide the configuration implementation
     * @param key  property key
     * @return   value of key or null
     */
    public String getString(String key);

    /**
     * Int property accessor method to hide the configuration implementation.
     *
     * @param key property key
     * @return int value
     */
    public int getInt( String key );

    /**
     * Int property accessor method to hide the configuration implementation.
     *
     * @param key  property key
     * @param defaultValue default value
     * @return int  value
     */
    public int getInt( String key, int defaultValue );

    /**
     * Boolean property accessor method to hide the configuration implementation.
     *
     * @param key  property key
     * @param def default default value if property not found
     * @return boolean  value of key or default value
     */
    public boolean getBoolean( String key, boolean def );

    /**
     * Return the velocity runtime configuration object.
     *
     * @return ExtendedProperties configuration object which houses
     *                       the velocity runtime properties.
     */
    public ExtendedProperties getConfiguration();

    /**
     * Return the specified application attribute.
     *
     * @param key The name of the attribute to retrieve.
     * @return The value of the attribute.
     */
    public Object getApplicationAttribute( Object key );

    /**
     * Set the specified application attribute.
     *
     * @param key The name of the attribute to set.
     * @param value The attribute value to set.
     * @return the displaced attribute value
     */
    public Object setApplicationAttribute( Object key, Object value );

    /**
     * Returns the configured class introspection/reflection
     * implementation.
     * @return The current Uberspect object.
     */
    public Uberspect getUberspect();

    /**
     * Returns a convenient Log instance that wraps the current LogChute.
     * @return A log object.
     */
    public Log getLog();

    /**
     * Returns the event handlers for the application.
     * @return The event handlers for the application.
     */
    public EventCartridge getApplicationEventCartridge();


    /**
     * Returns the configured method introspection/reflection
     * implementation.
     * @return The configured method introspection/reflection
     * implementation.
     */
    public Introspector getIntrospector();

    /**
     * Returns true if the RuntimeInstance has been successfully initialized.
     * @return True if the RuntimeInstance has been successfully initialized.
     */
    public boolean isInitialized();

    /**
     * Create a new parser instance.
     * @return A new parser instance.
     */
    public Parser createNewParser();

    /**
     * Retrieve a previously instantiated directive.
     * @param name name of the directive
     * @return the directive with that name, if any
     * @since 1.6
     */
    public Directive getDirective(String name);

}
