/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * Portions Copyright  2000-2004 The Apache Software Foundation
 *
 * This program and the accompanying materials are made 
 * available under the terms of the Apache Software License v2.0 which 
 * accompanies this distribution and is available at 
 * http://www.apache.org/licenses/LICENSE-2.0.
 * 
 * Contributors:
 *     IBM Corporation - derived implementation
 *******************************************************************************/

package org.eclipse.ant.internal.ui.model;

import java.io.File;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.PropertyHelper;
import org.apache.tools.ant.UnknownElement;
import org.apache.tools.ant.types.Path;

import org.eclipse.ant.internal.core.IAntCoreConstants;

/**
 * Derived from the original Ant Project class This class allows property values to be written multiple times. This facilitates incremental parsing of
 * the Ant build file It also attempts to ensure that we clean up after ourselves and allows more manipulation of properties resulting from
 * incremental parsing. Also allows the Eclipse additions to the Ant runtime classpath.
 */
public class AntModelProject extends Project {

	/**
	 * Delegate to maintain property chaining - to make sure our project is alerted to new properties being set
	 */
	class AntPropertyHelper implements PropertyHelper.PropertySetter {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.apache.tools.ant.PropertyHelper.PropertySetter#setNew(java.lang.String, java.lang.Object, org.apache.tools.ant.PropertyHelper)
		 */
		@Override
		public boolean setNew(String property, Object value, PropertyHelper propertyHelper) {
			setNewProperty(property, value.toString());
			return false;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.apache.tools.ant.PropertyHelper.PropertySetter#set(java.lang.String, java.lang.Object, org.apache.tools.ant.PropertyHelper)
		 */
		@Override
		public boolean set(String property, Object value, PropertyHelper propertyHelper) {
			return false;
		}
	}

	private AntPropertyNode fCurrentConfiguringPropertyNode;
	private Map<String, Object> idrefs = Collections.synchronizedMap(new HashMap<>());
	private static Object loaderLock = new Object();
	private Hashtable<String, AntClassLoader> loaders = null;

	/**
	 * Constructor
	 * <p>
	 * Allows us to register a {@link PropertyHelper.PropertySetter} delegate for this project
	 * </p>
	 * 
	 * @noreference This constructor is not intended to be referenced by clients.
	 */
	public AntModelProject() {
		PropertyHelper.getPropertyHelper(this).add(new AntPropertyHelper());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#setNewProperty(java.lang.String, java.lang.String)
	 */
	@Override
	public void setNewProperty(String name, String value) {
		if (PropertyHelper.getPropertyHelper(this).getProperty(name) != null) {
			return;
		}
		// allows property values to be over-written for this parse session
		// there is currently no way to remove properties from the Apache Ant project
		// the project resets it properties for each parse...see reset()
		if (fCurrentConfiguringPropertyNode != null) {
			fCurrentConfiguringPropertyNode.addProperty(name, value);
		}
		super.setProperty(name, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#fireBuildFinished(java.lang.Throwable)
	 */
	@Override
	public void fireBuildFinished(Throwable exception) {
		super.fireBuildFinished(exception);
		Enumeration<BuildListener> e = getBuildListeners().elements();
		while (e.hasMoreElements()) {
			BuildListener listener = e.nextElement();
			removeBuildListener(listener);
		}
	}

	/**
	 * Reset the project
	 */
	public void reset() {
		getTargets().clear();
		setDefault(null);
		setDescription(null);
		setName(IAntCoreConstants.EMPTY_STRING);
		synchronized (loaderLock) {
			if (loaders != null) {
				Iterator<Entry<String, AntClassLoader>> i = loaders.entrySet().iterator();
				Entry<String, AntClassLoader> e = null;
				while (i.hasNext()) {
					e = i.next();
					AntClassLoader acl = e.getValue();
					acl.cleanup();
					acl.clearAssertionStatus();
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#getProperty(java.lang.String)
	 */
	@Override
	public String getProperty(String name) {
		// override as we cannot remove properties from the Apache Ant project
		String result = super.getProperty(name);
		if (result == null) {
			return getUserProperty(name);
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#addIdReference(java.lang.String, java.lang.Object)
	 */
	@Override
	public void addIdReference(String id, Object value) {
		// XXX hack because we cannot look up references by id in Ant 1.8.x
		// see https://issues.apache.org/bugzilla/show_bug.cgi?id=49659
		idrefs.put(id, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#getReference(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getReference(String key) {
		T ref = super.getReference(key);/* references.get(key); */
		if (ref == null) {
			ref = (T) idrefs.get(key);
			if (ref instanceof UnknownElement) {
				UnknownElement ue = (UnknownElement) ref;
				ue.maybeConfigure();
				return (T) ue.getRealThing();
			}
		}
		return ref;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#getProperties()
	 */
	@Override
	public Hashtable<String, Object> getProperties() {
		// override as we cannot remove properties from the Apache Ant project
		Hashtable<String, Object> allProps = super.getProperties();
		allProps.putAll(getUserProperties());
		allProps.put("basedir", getBaseDir().getPath()); //$NON-NLS-1$
		return allProps;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#setBaseDir(java.io.File)
	 */
	@Override
	public void setBaseDir(File baseDir) throws BuildException {
		super.setBaseDir(baseDir);
		setNewProperty("basedir", getBaseDir().getPath()); //$NON-NLS-1$
	}

	/**
	 * @param node
	 *            the property node that is currently being configured
	 */
	public void setCurrentConfiguringProperty(AntPropertyNode node) {
		fCurrentConfiguringPropertyNode = node;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.Project#createClassLoader(org.apache.tools.ant.types.Path)
	 */
	@Override
	public AntClassLoader createClassLoader(Path path) {
		synchronized (loaderLock) {
			if (loaders == null) {
				loaders = new Hashtable<>(8);
			}
			Path p = path;
			if (p == null) {
				p = new Path(this);
			}
			String pstr = p.toString();
			AntClassLoader loader = loaders.get(pstr);
			if (loader == null) {
				loader = super.createClassLoader(path);
				if (path == null) {
					// use the "fake" Eclipse runtime classpath for Ant
					loader.setClassPath(Path.systemClasspath);
				}
				loaders.put(pstr, loader);
			}
			return loader;
		}
	}
}