/*******************************************************************************
 *  Copyright (c) 2000, 2013 IBM Corporation and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.internal.core.ant;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Ant;
import org.apache.tools.ant.taskdefs.CallTarget;
import org.eclipse.ant.core.AntCorePlugin;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;

/**
 * Reports progress and checks for cancellation of a script execution.
 */
public class ProgressBuildListener implements BuildListener {

	protected Map<Project, ProjectMonitors> projects;
	protected Project mainProject;
	protected Project parentProject;
	private Thread currentTaskThread;

	/**
	 * Contains the progress monitor instances for the various projects in a chain.
	 */
	protected static class ProjectMonitors {
		/**
		 * This field is null for the main project
		 */
		private Target mainTarget;
		private IProgressMonitor mainMonitor;
		private IProgressMonitor targetMonitor;
		private IProgressMonitor taskMonitor;

		protected IProgressMonitor getMainMonitor() {
			return mainMonitor;
		}

		protected Target getMainTarget() {
			return mainTarget;
		}

		protected IProgressMonitor getTargetMonitor() {
			return targetMonitor;
		}

		protected IProgressMonitor getTaskMonitor() {
			return taskMonitor;
		}

		protected void setMainMonitor(IProgressMonitor mainMonitor) {
			this.mainMonitor = mainMonitor;
		}

		protected void setMainTarget(Target mainTarget) {
			this.mainTarget = mainTarget;
		}

		protected void setTargetMonitor(IProgressMonitor targetMonitor) {
			this.targetMonitor = targetMonitor;
		}

		protected void setTaskMonitor(IProgressMonitor taskMonitor) {
			this.taskMonitor = taskMonitor;
		}

	}

	public ProgressBuildListener(Project project, List<String> targetNames, IProgressMonitor monitor) {
		projects = new HashMap<>();
		mainProject = project;
		ProjectMonitors monitors = new ProjectMonitors();
		IProgressMonitor localmonitor = monitor;
		if (localmonitor == null) {
			localmonitor = new NullProgressMonitor();
		}
		monitors.setMainMonitor(localmonitor);
		projects.put(mainProject, monitors);
		ArrayList<Target> targets = new ArrayList<>(targetNames.size());
		for (String targetName : targetNames) {
			Target target = mainProject.getTargets().get(targetName);
			if (target != null) {
				targets.add(target);
			}
		}
		int work = computeWork(targets);
		monitors.getMainMonitor().beginTask(IAntCoreConstants.EMPTY_STRING, work);
	}

	@Override
	public void buildStarted(BuildEvent event) {
		checkCanceled();
	}

	protected int computeWork(List<Target> targets) {
		int result = 0;
		for (Target target : targets) {
			result = result + countTarget(target, new ArrayList<>());
		}
		return result;
	}

	protected int countTarget(Target target, List<String> alreadySeen) {
		int result = 1;
		Project project = target.getProject();
		Hashtable<String, Target> targets = project.getTargets();
		String targetName;
		Target dependency;
		for (Enumeration<String> dependencies = target.getDependencies(); dependencies.hasMoreElements();) {
			targetName = dependencies.nextElement();
			if (alreadySeen.contains(targetName)) { // circular dependency or common dependency
				return result;
			}
			alreadySeen.add(targetName);
			dependency = targets.get(targetName);
			if (dependency != null) {
				result = result + countTarget(dependency, alreadySeen);
			}
		}
		// we have to handle antcall tasks as well
		for (Task task : target.getTasks()) {
			if (task instanceof CallTarget) {
				// As we do not have access to the information (at least in Ant 1.4.1)
				// describing what target is executed by this antcall task, we assume
				// a scenario where it depends on all targets of the project but itself.
				result = result + (targets.size() - 1);
			}
		}
		return result;
	}

	@Override
	public void buildFinished(BuildEvent event) {
		ProjectMonitors monitors = projects.get(mainProject);
		monitors.getMainMonitor().done();
		Set<Project> keys = projects.keySet();
		Iterator<Project> itr = keys.iterator();
		while (itr.hasNext()) {
			Project project = itr.next();
			project.removeBuildListener(this);
			project.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
		}
	}

	@Override
	public void targetStarted(BuildEvent event) {
		checkCanceled();
		Project currentProject = event.getProject();
		if (currentProject == null) {
			return;
		}
		Target target = event.getTarget();
		ProjectMonitors monitors = projects.get(currentProject);

		// if monitors is null we are in a new script
		if (monitors == null) {
			monitors = createMonitors(currentProject, target);
		}

		monitors.setTargetMonitor(subMonitorFor(monitors.getMainMonitor(), 1));
		int work = (target != null) ? target.getTasks().length : 100;
		monitors.getTargetMonitor().beginTask(IAntCoreConstants.EMPTY_STRING, work);
	}

	protected ProjectMonitors createMonitors(Project currentProject, Target target) {
		ProjectMonitors monitors = new ProjectMonitors();
		// remember the target so we can remove this monitors object later
		monitors.setMainTarget(target);
		ArrayList<Target> targets = new ArrayList<>(1);
		targets.add(target);
		int work = computeWork(targets);
		ProjectMonitors parentMonitors = null;
		if (parentProject == null) {
			parentMonitors = projects.get(mainProject);
			monitors.setMainMonitor(subMonitorFor(parentMonitors.getMainMonitor(), 1));
		} else {
			parentMonitors = projects.get(parentProject);
			parentProject = null;
			monitors.setMainMonitor(subMonitorFor(parentMonitors.getTaskMonitor(), 1));
		}
		monitors.getMainMonitor().beginTask(IAntCoreConstants.EMPTY_STRING, work);
		projects.put(currentProject, monitors);
		return monitors;
	}

	@Override
	public void targetFinished(BuildEvent event) {
		checkCanceled();
		Project currentProject = event.getProject();
		if (currentProject == null) {
			return;
		}
		ProjectMonitors monitors = projects.get(currentProject);
		if (monitors == null) {
			return;
		}
		monitors.getTargetMonitor().done();
		// if this is not the main project test if we are done with this project
		if ((currentProject != mainProject) && (monitors.getMainTarget() == event.getTarget())) {
			monitors.getMainMonitor().done();
			projects.remove(currentProject);
		}
	}

	@Override
	public void taskStarted(BuildEvent event) {
		checkCanceled();
		Project currentProject = event.getProject();
		if (currentProject == null) {
			return;
		}
		currentProject.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
		ProjectMonitors monitors = projects.get(currentProject);
		if (monitors == null) {
			return;
		}
		Task task = event.getTask();
		if (task == null) {
			return;
		}
		currentTaskThread = Thread.currentThread();
		monitors.setTaskMonitor(subMonitorFor(monitors.getTargetMonitor(), 1));
		monitors.getTaskMonitor().beginTask(IAntCoreConstants.EMPTY_STRING, 1);
		// If this script is calling another one, track the project chain.
		if (task instanceof Ant) {
			parentProject = currentProject;
		} else {
			currentProject.addReference(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR, monitors.getTaskMonitor());
		}
	}

	@Override
	public void taskFinished(BuildEvent event) {
		checkCanceled();
		Project project = event.getProject();
		if (project == null) {
			return;
		}
		project.getReferences().remove(AntCorePlugin.ECLIPSE_PROGRESS_MONITOR);
		ProjectMonitors monitors = projects.get(project);
		if (monitors == null) {
			return;
		}
		monitors.getTaskMonitor().done();
		currentTaskThread = null;
	}

	@Override
	public void messageLogged(BuildEvent event) {
		checkCanceled();
	}

	protected void checkCanceled() {
		// only cancel if the current task thread matches the current thread
		// do not want to throw an exception in a separate thread or process
		// see bug 32657
		if (currentTaskThread != null && currentTaskThread != Thread.currentThread()) {
			return;
		}
		ProjectMonitors monitors = projects.get(mainProject);
		if (monitors.getMainMonitor().isCanceled()) {
			currentTaskThread = null;
			throw new OperationCanceledException(InternalAntMessages.ProgressBuildListener_Build_cancelled);
		}
	}

	protected IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks) {
		if (monitor == null) {
			return new NullProgressMonitor();
		}
		if (monitor instanceof NullProgressMonitor) {
			return monitor;
		}
		return SubMonitor.convert(monitor, ticks);
	}
}
