/*
 *  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
 *
 *      https://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.tools.ant;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.tools.ant.taskdefs.PreSetDef;

/**
 * Wrapper class that holds all the information necessary to create a task
 * or data type that did not exist when Ant started, or one which
 * has had its definition updated to use a different implementation class.
 *
 */
public class UnknownElement extends Task {

    /**
     * Holds the name of the task/type or nested child element of a
     * task/type that hasn't been defined at parser time or has
     * been redefined since original creation.
     */
    private final String elementName;

    /**
     * Holds the namespace of the element.
     */
    private String namespace = "";

    /**
     * Holds the namespace qname of the element.
     */
    private String qname;

    /**
     * The real object after it has been loaded.
     */
    private Object realThing;

    /**
     * List of child elements (UnknownElements).
     */
    private List<UnknownElement> children = null;

    /** Specifies if a predefined definition has been done */
    private boolean presetDefed = false;

    /**
     * Creates an UnknownElement for the given element name.
     *
     * @param elementName The name of the unknown element.
     *                    Must not be <code>null</code>.
     */
    public UnknownElement(String elementName) {
        this.elementName = elementName;
    }

    /**
     * @return the list of nested UnknownElements for this UnknownElement.
     */
    public List<UnknownElement> getChildren() {
        return children;
    }

    /**
     * Returns the name of the XML element which generated this unknown
     * element.
     *
     * @return the name of the XML element which generated this unknown
     *         element.
     */
    public String getTag() {
        return elementName;
    }

    /**
     * Return the namespace of the XML element associated with this component.
     *
     * @return Namespace URI used in the xmlns declaration.
     */
    public String getNamespace() {
        return namespace;
    }

    /**
     * Set the namespace of the XML element associated with this component.
     * This method is typically called by the XML processor.
     * If the namespace is "ant:current", the component helper
     * is used to get the current antlib uri.
     *
     * @param namespace URI used in the xmlns declaration.
     */
    public void setNamespace(String namespace) {
        if (namespace.equals(ProjectHelper.ANT_CURRENT_URI)) {
            ComponentHelper helper = ComponentHelper.getComponentHelper(
                getProject());
            namespace = helper.getCurrentAntlibUri();
        }
        this.namespace = namespace == null ? "" : namespace;
    }

    /**
     * Return the qname of the XML element associated with this component.
     *
     * @return namespace Qname used in the element declaration.
     */
    public String getQName() {
        return qname;
    }

    /**
     * Set the namespace qname of the XML element.
     * This method is typically called by the XML processor.
     *
     * @param qname the qualified name of the element
     */
    public void setQName(String qname) {
        this.qname = qname;
    }


    /**
     * Get the RuntimeConfigurable instance for this UnknownElement, containing
     * the configuration information.
     *
     * @return the configuration info.
     */
    public RuntimeConfigurable getWrapper() {
        return super.getWrapper();
    }

    /**
     * Creates the real object instance and child elements, then configures
     * the attributes and text of the real object. This unknown element
     * is then replaced with the real object in the containing target's list
     * of children.
     *
     * @exception BuildException if the configuration fails
     */
    public void maybeConfigure() throws BuildException {
        if (realThing != null) {
            return;
        }
        configure(makeObject(this, getWrapper()));
    }

    /**
     * Configure the given object from this UnknownElement
     *
     * @param realObject the real object this UnknownElement is representing.
     *
     */
    public void configure(Object realObject) {
        if (realObject == null) {
            return;
        }
        realThing = realObject;

        getWrapper().setProxy(realThing);
        Task task = null;
        if (realThing instanceof Task) {
            task = (Task) realThing;

            task.setRuntimeConfigurableWrapper(getWrapper());

            // For Script example that modifies id'ed tasks in other
            // targets to work. *very* Ugly
            // The reference is replaced by RuntimeConfigurable
            if (getWrapper().getId() != null) {
                this.getOwningTarget().replaceChild(this, (Task) realThing);
            }
       }


        // configure attributes of the object and it's children. If it is
        // a task container, defer the configuration till the task container
        // attempts to use the task

        if (task != null) {
            task.maybeConfigure();
        } else {
            getWrapper().maybeConfigure(getProject());
        }

        handleChildren(realThing, getWrapper());
    }

    /**
     * Handles output sent to System.out by this task or its real task.
     *
     * @param output The output to log. Should not be <code>null</code>.
     */
    protected void handleOutput(String output) {
        if (realThing instanceof Task) {
            ((Task) realThing).handleOutput(output);
        } else {
            super.handleOutput(output);
        }
    }

    /**
     * Delegate to realThing if present and if it as task.
     * @see Task#handleInput(byte[], int, int)
     * @param buffer the buffer into which data is to be read.
     * @param offset the offset into the buffer at which data is stored.
     * @param length the amount of data to read.
     *
     * @return the number of bytes read.
     *
     * @exception IOException if the data cannot be read.
     * @since Ant 1.6
     */
    protected int handleInput(byte[] buffer, int offset, int length)
        throws IOException {
        if (realThing instanceof Task) {
            return ((Task) realThing).handleInput(buffer, offset, length);
        }
        return super.handleInput(buffer, offset, length);
    }

    /**
     * Handles output sent to System.out by this task or its real task.
     *
     * @param output The output to log. Should not be <code>null</code>.
     */
    protected void handleFlush(String output) {
        if (realThing instanceof Task) {
            ((Task) realThing).handleFlush(output);
        } else {
            super.handleFlush(output);
        }
    }

    /**
     * Handles error output sent to System.err by this task or its real task.
     *
     * @param output The error output to log. Should not be <code>null</code>.
     */
    protected void handleErrorOutput(String output) {
        if (realThing instanceof Task) {
            ((Task) realThing).handleErrorOutput(output);
        } else {
            super.handleErrorOutput(output);
        }
    }

    /**
     * Handles error output sent to System.err by this task or its real task.
     *
     * @param output The error output to log. Should not be <code>null</code>.
     */
    protected void handleErrorFlush(String output) {
        if (realThing instanceof Task) {
            ((Task) realThing).handleErrorFlush(output);
        } else {
            super.handleErrorFlush(output);
        }
    }

    /**
     * Executes the real object if it's a task. If it's not a task
     * (e.g. a data type) then this method does nothing.
     */
    public void execute() {
        if (realThing == null) {
            // Got here if the runtimeconfigurable is not enabled.
            return;
        }
        try {
            if (realThing instanceof Task) {
                ((Task) realThing).execute();
            }
        } finally {
            // Finished executing the task
            // null it (unless it has an ID) to allow
            // GC do its job
            // If this UE is used again, a new "realthing" will be made
            if (getWrapper().getId() == null) {
                realThing = null;
                getWrapper().setProxy(null);
            }
        }
    }

    /**
     * Adds a child element to this element.
     *
     * @param child The child element to add. Must not be <code>null</code>.
     */
    public void addChild(UnknownElement child) {
        if (children == null) {
            children = new ArrayList<>();
        }
        children.add(child);
    }

    /**
     * Creates child elements, creates children of the children
     * (recursively), and sets attributes of the child elements.
     *
     * @param parent The configured object for the parent.
     *               Must not be <code>null</code>.
     *
     * @param parentWrapper The wrapper containing child wrappers
     *                      to be configured. Must not be <code>null</code>
     *                      if there are any children.
     *
     * @exception BuildException if the children cannot be configured.
     */
    protected void handleChildren(
        Object parent,
        RuntimeConfigurable parentWrapper)
        throws BuildException {
        if (parent instanceof TypeAdapter) {
            parent = ((TypeAdapter) parent).getProxy();
        }

        String parentUri = getNamespace();
        Class<?> parentClass = parent.getClass();
        IntrospectionHelper ih = IntrospectionHelper.getHelper(getProject(), parentClass);

        if (children != null) {
            Iterator<UnknownElement> it = children.iterator();
            for (int i = 0; it.hasNext(); i++) {
                RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
                UnknownElement child = it.next();
                try {
                    if (!childWrapper.isEnabled(child)) {
                        if (ih.supportsNestedElement(
                                parentUri, ProjectHelper.genComponentName(
                                    child.getNamespace(), child.getTag()))) {
                            continue;
                        }
                        // fall tru and fail in handlechild (unsupported element)
                    }
                    if (!handleChild(
                            parentUri, ih, parent, child, childWrapper)) {
                        if (!(parent instanceof TaskContainer)) {
                            ih.throwNotSupported(getProject(), parent,
                                                 child.getTag());
                        } else {
                            // a task container - anything could happen - just add the
                            // child to the container
                            TaskContainer container = (TaskContainer) parent;
                            container.addTask(child);
                        }
                    }
                } catch (UnsupportedElementException ex) {
                    throw new BuildException(
                        parentWrapper.getElementTag()
                        + " doesn't support the nested \"" + ex.getElement()
                        + "\" element.", ex);
                }
            }
        }
    }

    /**
     * @return the component name - uses ProjectHelper#genComponentName()
     */
    protected String getComponentName() {
        return ProjectHelper.genComponentName(getNamespace(), getTag());
    }

    /**
     * This is used then the realobject of the UE is a PreSetDefinition.
     * This is also used when a presetdef is used on a presetdef
     * The attributes, elements and text are applied to this
     * UE.
     *
     * @param u an UnknownElement containing the attributes, elements and text
     */
    public void applyPreSet(UnknownElement u) {
        if (presetDefed) {
            return;
        }
        // Do the runtime
        getWrapper().applyPreSet(u.getWrapper());
        if (u.children != null) {
            List<UnknownElement> newChildren = new ArrayList<>(u.children);
            if (children != null) {
                newChildren.addAll(children);
            }
            children = newChildren;
        }
        presetDefed = true;
    }

    /**
     * Creates a named task or data type. If the real object is a task,
     * it is configured up to the init() stage.
     *
     * @param ue The unknown element to create the real object for.
     *           Must not be <code>null</code>.
     * @param w  Ignored in this implementation.
     *
     * @return the task or data type represented by the given unknown element.
     */
    protected Object makeObject(UnknownElement ue, RuntimeConfigurable w) {
        if (!w.isEnabled(ue)) {
            return null;
        }
        ComponentHelper helper = ComponentHelper.getComponentHelper(
            getProject());
        String name = ue.getComponentName();
        Object o = helper.createComponent(ue, ue.getNamespace(), name);
        if (o == null) {
            throw getNotFoundException("task or type", name);
        }
        if (o instanceof PreSetDef.PreSetDefinition) {
            PreSetDef.PreSetDefinition def = (PreSetDef.PreSetDefinition) o;
            o = def.createObject(ue.getProject());
            if (o == null) {
                throw getNotFoundException(
                    "preset " + name,
                    def.getPreSets().getComponentName());
            }
            ue.applyPreSet(def.getPreSets());
            if (o instanceof Task) {
                Task task = (Task) o;
                task.setTaskType(ue.getTaskType());
                task.setTaskName(ue.getTaskName());
                task.init();
            }
        }
        if (o instanceof UnknownElement) {
            o = ((UnknownElement) o).makeObject((UnknownElement) o, w);
        }
        if (o instanceof Task) {
            ((Task) o).setOwningTarget(getOwningTarget());
        }
        if (o instanceof ProjectComponent) {
            ((ProjectComponent) o).setLocation(getLocation());
        }
        return o;
    }

    /**
     * Creates a named task and configures it up to the init() stage.
     *
     * @param ue The UnknownElement to create the real task for.
     *           Must not be <code>null</code>.
     * @param w  Ignored.
     *
     * @return the task specified by the given unknown element, or
     *         <code>null</code> if the task name is not recognised.
     */
    protected Task makeTask(UnknownElement ue, RuntimeConfigurable w) {
        Task task = getProject().createTask(ue.getTag());

        if (task != null) {
            task.setLocation(getLocation());
            // UnknownElement always has an associated target
            task.setOwningTarget(getOwningTarget());
            task.init();
        }
        return task;
    }

    /**
     * Returns a very verbose exception for when a task/data type cannot
     * be found.
     *
     * @param what The kind of thing being created. For example, when
     *             a task name could not be found, this would be
     *             <code>"task"</code>. Should not be <code>null</code>.
     * @param name The name of the element which could not be found.
     *             Should not be <code>null</code>.
     *
     * @return a detailed description of what might have caused the problem.
     */
    protected BuildException getNotFoundException(String what,
                                                  String name) {
        ComponentHelper helper = ComponentHelper.getComponentHelper(getProject());
        String msg = helper.diagnoseCreationFailure(name, what);
        return new BuildException(msg, getLocation());
    }

    /**
     * Returns the name to use in logging messages.
     *
     * @return the name to use in logging messages.
     */
    public String getTaskName() {
        return !(realThing instanceof Task) ? super.getTaskName()
                                            : ((Task) realThing).getTaskName();
    }

    /**
     * Returns the task instance after it has been created and if it is a task.
     *
     * @return a task instance or <code>null</code> if the real object is not
     *         a task.
     */
    public Task getTask() {
        if (realThing instanceof Task) {
            return (Task) realThing;
        }
        return null;
    }

    /**
     * Return the configured object
     *
     * @return the real thing whatever it is
     *
     * @since ant 1.6
     */
    public Object getRealThing() {
        return realThing;
    }

    /**
     * Set the configured object
     * @param realThing the configured object
     * @since ant 1.7
     */
    public void setRealThing(Object realThing) {
        this.realThing = realThing;
    }

    /**
     * Try to create a nested element of <code>parent</code> for the
     * given tag.
     *
     * @return whether the creation has been successful
     */
    private boolean handleChild(
        String parentUri,
        IntrospectionHelper ih,
        Object parent, UnknownElement child,
        RuntimeConfigurable childWrapper) {
        String childName = ProjectHelper.genComponentName(
            child.getNamespace(), child.getTag());
        if (ih.supportsNestedElement(parentUri, childName, getProject(),
                                     parent)) {
            IntrospectionHelper.Creator creator = null;
            try {
                creator = ih.getElementCreator(getProject(), parentUri,
                                               parent, childName, child);
            } catch (UnsupportedElementException use) {
                if (!ih.isDynamic()) {
                    throw use;
                }
                // can't trust supportsNestedElement for dynamic elements
                return false;
            }
            creator.setPolyType(childWrapper.getPolyType());
            Object realChild = creator.create();
            if (realChild instanceof PreSetDef.PreSetDefinition) {
                PreSetDef.PreSetDefinition def =
                    (PreSetDef.PreSetDefinition) realChild;
                realChild = creator.getRealObject();
                child.applyPreSet(def.getPreSets());
            }
            childWrapper.setCreator(creator);
            childWrapper.setProxy(realChild);
            if (realChild instanceof Task) {
                Task childTask = (Task) realChild;
                childTask.setRuntimeConfigurableWrapper(childWrapper);
                childTask.setTaskName(childName);
                childTask.setTaskType(childName);
            }
            if (realChild instanceof ProjectComponent) {
                ((ProjectComponent) realChild).setLocation(child.getLocation());
            }
            childWrapper.maybeConfigure(getProject());
            child.handleChildren(realChild, childWrapper);
            creator.store();
            return true;
        }
        return false;
    }

    /**
     * like contents equals, but ignores project
     * @param obj the object to check against
     * @return true if this UnknownElement has the same contents the other
     */
    public boolean similar(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!getClass().getName().equals(obj.getClass().getName())) {
            return false;
        }
        UnknownElement other = (UnknownElement) obj;
        // Are the names the same ?
        if (!Objects.equals(elementName, other.elementName)) {
            return false;
        }
        if (!namespace.equals(other.namespace)) {
            return false;
        }
        if (!qname.equals(other.qname)) {
            return false;
        }
        // Are attributes the same ?
        if (!getWrapper().getAttributeMap().equals(
                other.getWrapper().getAttributeMap())) {
            return false;
        }
        // Is the text the same?
        //   Need to use equals on the string and not
        //   on the stringbuffer as equals on the string buffer
        //   does not compare the contents.
        if (!getWrapper().getText().toString().equals(
                other.getWrapper().getText().toString())) {
            return false;
        }
        // Are the sub elements the same ?
        final int childrenSize = children == null ? 0 : children.size();
        if (childrenSize == 0) {
            return other.children == null || other.children.isEmpty();
        }
        if (other.children == null) {
            return false;
        }
        if (childrenSize != other.children.size()) {
            return false;
        }
        for (int i = 0; i < childrenSize; ++i) {
            // children cannot be null childrenSize would have been 0
            UnknownElement child = children.get(i); //NOSONAR
            if (!child.similar(other.children.get(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Make a copy of the unknown element and set it in the new project.
     * @param newProject the project to create the UE in.
     * @return the copied UE.
     */
    public UnknownElement copy(Project newProject) {
        UnknownElement ret = new UnknownElement(getTag());
        ret.setNamespace(getNamespace());
        ret.setProject(newProject);
        ret.setQName(getQName());
        ret.setTaskType(getTaskType());
        ret.setTaskName(getTaskName());
        ret.setLocation(getLocation());
        if (getOwningTarget() == null) {
            Target t = new Target();
            t.setProject(getProject());
            ret.setOwningTarget(t);
        } else {
            ret.setOwningTarget(getOwningTarget());
        }
        RuntimeConfigurable copyRC = new RuntimeConfigurable(
            ret, getTaskName());
        copyRC.setPolyType(getWrapper().getPolyType());
        Map<String, Object> m = getWrapper().getAttributeMap();
        for (Map.Entry<String, Object> entry : m.entrySet()) {
            copyRC.setAttribute(entry.getKey(), (String) entry.getValue());
        }
        copyRC.addText(getWrapper().getText().toString());

        for (RuntimeConfigurable r : Collections.list(getWrapper().getChildren())) {
            UnknownElement ueChild = (UnknownElement) r.getProxy();
            UnknownElement copyChild = ueChild.copy(newProject);
            copyRC.addChild(copyChild.getWrapper());
            ret.addChild(copyChild);
        }
        return ret;
    }
}
