/*
 * 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.commons.jelly.tags.ant;

import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.jelly.JellyTagException;
import org.apache.commons.jelly.MapTagSupport;
import org.apache.commons.jelly.Tag;
import org.apache.commons.jelly.XMLOutput;
import org.apache.commons.jelly.expression.Expression;
import org.apache.commons.jelly.impl.BeanSource;
import org.apache.commons.jelly.impl.StaticTag;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DemuxOutputStream;
import org.apache.tools.ant.IntrospectionHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.TaskAdapter;
import org.apache.tools.ant.TaskContainer;
import org.apache.tools.ant.types.DataType;

/**
 * Tag supporting ant's Tasks as well as
 * dynamic runtime behaviour for 'unknown' tags.
 *
 * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 */
public class AntTag extends MapTagSupport implements TaskSource {

    /** The Log to which logging calls will be made. */
    private static final Log log = LogFactory.getLog(AntTag.class);

    private static final Class[] addTaskParamTypes = { String.class };

    /** store the name of the manifest tag for special handling */
    private static final String ANT_MANIFEST_TAG = "manifest";

    /** The name of this tag. */
    protected String tagName;

    /** The general object underlying this tag. */
    protected Object object;

    /** Task, if this tag represents a task. */
    protected Task task;


    /** Construct with a project and tag name.
     *
     *  @param tagName The name on the tag.
     */
    public AntTag(String tagName) {
        this.tagName = tagName;
    }

    public String toString() {
        return "[AntTag: name=" + getTagName() + "]";
    }

    // TaskSource interface
    //-------------------------------------------------------------------------

    /** Retrieve the general object underlying this tag.
     *
     *  @return The object underlying this tag.
     */
    public Object getTaskObject() {
        return this.object;
    }

    /**
     * Allows nested tags to set a property on the task object of this tag
     */
    public void setTaskProperty(String name, Object value) throws JellyTagException {
        Object object = getTaskObject();
        if ( object != null ) {
            setBeanProperty( object, name, value );
        }
    }

    // Tag interface
    //-------------------------------------------------------------------------
    public void doTag(XMLOutput output) throws JellyTagException {

        Project project = getAntProject();
        String tagName = getTagName();
        Object parentObject = findBeanAncestor();
        Object parentTask = findParentTaskObject();

        // lets assume that Task instances are not nested inside other Task instances
        // for example <manifest> inside a <jar> should be a nested object, where as
        // if the parent is not a Task the <manifest> should create a ManifestTask
        //
        // also its possible to have a root Ant tag which isn't a task, such as when
        // defining <fileset id="...">...</fileset>

        Object nested = null;
        if (parentObject != null && !( parentTask instanceof TaskContainer) ) {
            nested = createNestedObject( parentObject, tagName );
        }

        if (nested == null) {
            task = createTask( tagName );

            if (task != null) {

                if ( log.isDebugEnabled() ) {
                    log.debug( "Creating an ant Task for name: " + tagName );
                }

                // the following algorithm follows the lifetime of a tag
                // http://jakarta.apache.org/ant/manual/develop.html#writingowntask
                // kindly recommended by Stefan Bodewig

                // create and set its project reference
                if ( task instanceof TaskAdapter ) {
                    setObject( ((TaskAdapter)task).getProxy() );
                }
                else {
                    setObject( task );
                }

                // set the task ID if one is given
                Object id = getAttributes().remove( "id" );
                if ( id != null ) {
                    project.addReference( (String) id, task );
                }

                // ### we might want to spoof a Target setting here

                // now lets initialize
                task.init();

                // now lets invoke the body to call all the createXXX() or addXXX() methods
                String body = getBodyText();

                // now lets set any attributes of this tag...
                setBeanProperties();

                // now lets set the addText() of the body content, if its applicable
                Method method = MethodUtils.getAccessibleMethod( task.getClass(),
                                                                 "addText",
                                                                 addTaskParamTypes );
                if (method != null) {
                    Object[] args = { body };
                    try {
                        method.invoke(this.task, args);
                    }
                    catch (IllegalAccessException e) {
                        throw new JellyTagException(e);
                    }
                    catch (InvocationTargetException e) {
                        throw new JellyTagException(e);
                    }
                }

                // now lets set all the attributes of the child elements
                // XXXX: to do!

                // now we're ready to invoke the task
                // XXX: should we call execute() or perform()?
                // according to org.apache.tools.ant.Main, redirect stdout and stderr
                PrintStream initialOut = System.out;
                PrintStream initialErr = System.err;
                PrintStream newOut = new PrintStream(new DemuxOutputStream(project, false));
                PrintStream newErr = new PrintStream(new DemuxOutputStream(project, true));
                try {
                    System.setOut(newOut);
                    System.setErr(newErr);
                    task.perform();
                } finally {
                    System.setOut(initialOut);
                    System.setErr(initialErr);
                }
            }
        }

        if (task == null) {

            if (nested == null) {

                if ( log.isDebugEnabled() ) {
                    log.debug( "Trying to create a data type for tag: " + tagName );
                }
                nested = createDataType( tagName );
            }
            else {
                if ( log.isDebugEnabled() ) {
                    log.debug( "Created nested property tag: " + tagName );
                }
            }

            if ( nested != null ) {
                setObject( nested );

                // set the task ID if one is given
                Object id = getAttributes().remove( "id" );
                if ( id != null ) {
                    project.addReference( (String) id, nested );
                }

                // TODO: work out why we always set the name attribute.
                // See JELLY-105.
//                try{
//                    PropertyUtils.setProperty( nested, "name", tagName );
//                }
//                catch (Exception e) {
//                    log.warn( "Caught exception setting nested name: " + tagName, e );
//                }

                // now lets invoke the body
                String body = getBodyText();

                // now lets set any attributes of this tag...
                setBeanProperties();

                // now lets add it to its parent
                if ( parentObject != null ) {
                    IntrospectionHelper ih = IntrospectionHelper.getHelper( parentObject.getClass() );
                    try {
                        if (log.isDebugEnabled()) {
                            log.debug("About to set the: " + tagName
                                + " property on: " + safeToString(parentObject) + " to value: "
                                + nested + " with type: " + nested.getClass()
                            );
                        }

                        ih.storeElement( project, parentObject, nested, tagName.toLowerCase() );
                    }
                    catch (Exception e) {
                        log.warn( "Caught exception setting nested: " + tagName, e );
                    }

                    // now try to set the property for good measure
                    // as the storeElement() method does not
                    // seem to call any setter methods of non-String types
                    try {
                        BeanUtils.setProperty( parentObject, tagName, nested );
                    }
                    catch (Exception e) {
                        log.debug("Caught exception trying to set property: " + tagName + " on: " + safeToString(parentObject));
                    }
                }
            }
            else {
                log.warn("Could not convert tag: " + tagName + " into an Ant task, data type or property");

                // lets treat this tag as static XML...
                StaticTag tag = new StaticTag("", tagName, tagName);
                tag.setParent( getParent() );
                tag.setBody( getBody() );

                tag.setContext(context);

                for (Iterator iter = getAttributes().entrySet().iterator(); iter.hasNext();) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String name = (String) entry.getKey();
                    Object value = entry.getValue();

                    tag.setAttribute(name, value);
                }

                tag.doTag(output);
            }
        }
    }


    // Properties
    //-------------------------------------------------------------------------
    public String getTagName() {
        return this.tagName;
    }

    /** Set the object underlying this tag.
     *
     *  @param object The object.
     */
    public void setObject(Object object) {
        this.object = object;
    }

    public Project getAntProject() {
        Project project = AntTagLibrary.getProject(context);
        if (project == null) {
            throw new NullPointerException("No Ant Project object is available");
        }
        return project;
    }

    // Implementation methods
    //-------------------------------------------------------------------------

    /**
     * Sets the properties on the Ant task
     */
    public void setBeanProperties() throws JellyTagException {
        Object object = getTaskObject();
        if ( object != null ) {
            Map map = getAttributes();
            for ( Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
                Map.Entry entry = (Map.Entry) iter.next();
                String name = (String) entry.getKey();
                Object value = entry.getValue();
                setBeanProperty( object, name, value );
            }
        }
    }

    public void setAttribute(String name, Object value) {
        if ( value == null ) {
            // should we send in null?
            super.setAttribute( name, "" );
        }
        else {
            if ( value instanceof Expression )
            {
                super.setAttribute( name, ((Expression) value).evaluateRecurse(context) );
            }
            else
            {
                super.setAttribute( name, value.toString() );
            }
        }
    }

    public void setBeanProperty(Object object, String name, Object value) throws JellyTagException {
        if ( log.isDebugEnabled() ) {
            log.debug( "Setting bean property on: "+  safeToString(object )+ " name: " + name + " value: " + safeToString(value));
        }

        IntrospectionHelper ih = IntrospectionHelper.getHelper( object.getClass() );

        if ( value instanceof String ) {
            try {
                ih.setAttribute( getAntProject(), object, name.toLowerCase(), (String) value );
                return;
            }
            catch (Exception e) {
                // ignore: not a valid property
            }
        }

        try {

            ih.storeElement( getAntProject(), object, value, name );
        }
        catch (Exception e) {

            try {
                // let any exceptions bubble up from here
                BeanUtils.setProperty( object, name, value );
            }
            catch (IllegalAccessException ex) {
                throw new JellyTagException(ex);
            }
            catch (InvocationTargetException ex) {
                throw new JellyTagException(ex);
            }
        }
    }


    /**
     * Creates a nested object of the given object with the specified name
     */
    public Object createNestedObject(Object object, String name) {
        Object dataType = null;
        if ( object != null ) {
            IntrospectionHelper ih = IntrospectionHelper.getHelper( object.getClass() );

            if ( ih != null && ! (object instanceof AntTag)) {
                try {
                    dataType = ih.createElement( getAntProject(), object, name.toLowerCase() );
                } catch (BuildException be) {
                    if (object instanceof Tag)
                    {
                        if (log.isDebugEnabled()) {
                            log.debug("Failed attempt to create an ant datatype for a jelly tag", be);
                        }
                    } else {
                        log.error(be);
                    }
                }
            }
        }

        if ( dataType == null ) {
            dataType = createDataType( name );
        }

        return dataType;
    }

    public Object createDataType(String name) {

        Object dataType = null;

        Class type = (Class) getAntProject().getDataTypeDefinitions().get(name);

        if ( type != null ) {

            Constructor ctor = null;
            boolean noArg = false;

            // DataType can have a "no arg" constructor or take a single
            // Project argument.
            try {
                ctor = type.getConstructor(new Class[0]);
                noArg = true;
            }
            catch (NoSuchMethodException nse) {
                try {
                    ctor = type.getConstructor(new Class[] { Project.class });
                    noArg = false;
                } catch (NoSuchMethodException nsme) {
                    log.info("datatype '" + name
                        + "' didn't have a constructor with an Ant Project", nsme);
                }
            }

            if (noArg) {
                dataType = createDataType(ctor, new Object[0], name, "no-arg constructor");
            }
            else {
                dataType = createDataType(ctor, new Object[] { getAntProject() }, name, "an Ant project");
            }
            if (dataType != null && dataType instanceof DataType) {
                ((DataType)dataType).setProject( getAntProject() );
            }
        }

        return dataType;
    }

    /**
     * @return an object create with the given constructor and args.
     * @param ctor a constructor to use creating the object
     * @param args the arguments to pass to the constructor
     * @param name the name of the data type being created
     * @param argDescription a human readable description of the args passed
     */
    private Object createDataType(Constructor ctor, Object[] args, String name, String argDescription) {
        try {
            Object datatype = ctor.newInstance(args);
            return datatype;
        } catch (InstantiationException ie) {
            log.error("datatype '" + name + "' couldn't be created with " + argDescription, ie);
        } catch (IllegalAccessException iae) {
            log.error("datatype '" + name + "' couldn't be created with " + argDescription, iae);
        } catch (InvocationTargetException ite) {
            log.error("datatype '" + name + "' couldn't be created with " + argDescription, ite);
        }
        return null;
    }

    /**
     * @param taskName
     * @return
     * @throws JellyTagException
     */
    public Task createTask(String taskName) throws JellyTagException {
        return createTask( taskName,
                           (Class) getAntProject().getTaskDefinitions().get( taskName ) );
    }

    public Task createTask(String taskName,
                           Class taskType) throws JellyTagException {

        if (taskType == null) {
            return null;
        }

        Object o = null;
        try {
            o = taskType.newInstance();
        } catch (InstantiationException e) {
            throw new JellyTagException(e);
        }
        catch (IllegalAccessException e) {
            throw new JellyTagException(e);
        }

        Task task = null;
        if ( o instanceof Task ) {
            task = (Task) o;
        }
        else {
            TaskAdapter taskA=new TaskAdapter();
            taskA.setProxy( o );
            task=taskA;
        }

        task.setProject(getAntProject());
        task.setTaskName(taskName);

        return task;
    }

    /**
     * Attempts to look up in the parent hierarchy for a tag that implements the
     * TaskSource interface, which returns an Ant Task object or that implements
     * BeanSource interface which creates a bean,
     * or will return the parent tag, which is also a bean.
     */
    protected Object findBeanAncestor() throws JellyTagException {
        Tag tag = getParent();
        while (tag != null) {
            if (tag instanceof BeanSource) {
                BeanSource beanSource = (BeanSource) tag;
                return beanSource.getBean();
            }
            if (tag instanceof TaskSource) {
                TaskSource taskSource = (TaskSource) tag;
                return taskSource.getTaskObject();
            }
            tag = tag.getParent();
        }
        return getParent();
    }

    /**
     * Walks the hierarchy until it finds a parent TaskSource and returns its source or returns null
     */
    protected Object findParentTaskObject() throws JellyTagException {
        Tag tag = getParent();
        while (tag != null) {
            if (tag instanceof TaskSource) {
                TaskSource source = (TaskSource) tag;
                return source.getTaskObject();
            }
            tag = tag.getParent();
        }
        return null;
    }

    private String safeToString(Object o) {
        if(o==null) return "null";
        String r = null;
        try {
            r = o.toString();
        } catch(Exception ex) {}
        if(r == null)
            r = "(object of class " + o.getClass() + ")";
        return r;
    }

}
