package org.eclipse.dltk.core.tests.launching;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.core.tests.model.AbstractModelTests;
import org.eclipse.dltk.debug.core.ExtendedDebugEventDetails;
import org.eclipse.dltk.debug.core.model.IScriptLineBreakpoint;
import org.eclipse.dltk.debug.core.model.IScriptStackFrame;
import org.eclipse.dltk.debug.core.model.IScriptThread;
import org.eclipse.dltk.internal.debug.core.model.ScriptDebugTarget;
import org.eclipse.dltk.internal.debug.core.model.ScriptLineBreakpoint;
import org.eclipse.dltk.internal.debug.core.model.ScriptThread;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.IInterpreterInstallType;
import org.eclipse.dltk.launching.InterpreterConfig;
import org.eclipse.dltk.launching.InterpreterSearcher;
import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants;

public abstract class ScriptLaunchingTests extends AbstractModelTests {

	protected IScriptProject scriptProject;

	protected IInterpreterInstall[] interpreterInstalls;

	public ScriptLaunchingTests(String testProjectName, String name) {
		super(testProjectName, name);
	}

	// Configuration
	@Override
	public void setUpSuite() throws Exception {
		super.setUpSuite();
		scriptProject = setUpScriptProject(getProjectName());

		final IProject project = scriptProject.getProject();
		IProjectDescription description = project.getDescription();
		description.setNatureIds(new String[] { getNatureId() });
		project.setDescription(description, null);

		if (!hasPredefinedInterpreters()) {
			interpreterInstalls = searchInstalls(getNatureId());
		} else {
			interpreterInstalls = getPredefinedInterpreterInstalls();
		}
	}

	/**
	 * Should return predefined interpreters. Used with
	 * hasPredefinedInterpreters method as true.
	 * 
	 * @return Not null array of interpreter installs.
	 */
	protected IInterpreterInstall[] getPredefinedInterpreterInstalls() {
		return new IInterpreterInstall[0];
	}

	@Override
	public void tearDownSuite() throws Exception {
		deleteProject(getProjectName());
		super.tearDownSuite();
	}

	// Helper methods
	protected ILaunchConfiguration createTestLaunchConfiguration(
			final String natureId, final String projectName,
			final String script, final String arguments) {
		return new ILaunchConfiguration() {
			@Override
			public boolean contentsEqual(ILaunchConfiguration configuration) {
				return false;
			}

			@Override
			public ILaunchConfigurationWorkingCopy copy(String name)
					throws CoreException {
				return null;
			}

			@Override
			public void delete() throws CoreException {

			}

			@Override
			public boolean exists() {
				return false;
			}

			@Override
			public boolean getAttribute(String attributeName,
					boolean defaultValue) throws CoreException {
				if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_DEFAULT_BUILDPATH)) {
					return true;
				} else if (attributeName
						.equals(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES)) {
					return true;
				}

				return defaultValue;
			}

			@Override
			public int getAttribute(String attributeName, int defaultValue)
					throws CoreException {
				if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_DLTK_DBGP_WAITING_TIMEOUT)) {
					return 10000;
				}
				return defaultValue;
			}

			@Override
			public List getAttribute(String attributeName, List defaultValue)
					throws CoreException {
				return defaultValue;
			}

			@Override
			public Set getAttribute(String attributeName, Set defaultValue)
					throws CoreException {
				return defaultValue;
			}

			@Override
			public Map getAttribute(String attributeName, Map defaultValue)
					throws CoreException {
				if (attributeName
						.equals(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES)) {
					Map<Object, Object> env = new HashMap<Object, Object>();
					configureEnvironment(env);
					return env;
				}
				return defaultValue;
			}

			@Override
			public String getAttribute(String attributeName, String defaultValue)
					throws CoreException {

				if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME)) {
					return script;
				} else if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME)) {
					return projectName;
				} else if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY)) {
					return null;
				} else if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_SCRIPT_ARGUMENTS)) {
					return arguments;
				} else if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_INTERPRETER_ARGUMENTS)) {
					return "";
				} else if (attributeName
						.equals(ScriptLaunchConfigurationConstants.ATTR_SCRIPT_NATURE)) {
					return natureId;
				}
				return defaultValue;
			}

			@Override
			public Map getAttributes() throws CoreException {
				return null;
			}

			@Override
			public String getCategory() throws CoreException {
				return null;
			}

			@Override
			public IFile getFile() {
				return ScriptLaunchingTests.this.getFile(projectName + '/'
						+ script);
			}

			@Override
			public IPath getLocation() {
				return null;
			}

			@Override
			public IResource[] getMappedResources() throws CoreException {
				return null;
			}

			@Override
			public String getMemento() throws CoreException {
				return null;
			}

			@Override
			public Set getModes() throws CoreException {
				return null;
			}

			@Override
			public String getName() {
				return null;
			}

			@Override
			public ILaunchDelegate getPreferredDelegate(Set modes)
					throws CoreException {
				return null;
			}

			@Override
			public ILaunchConfigurationType getType() throws CoreException {
				return null;
			}

			@Override
			public ILaunchConfigurationWorkingCopy getWorkingCopy()
					throws CoreException {
				return null;
			}

			@Override
			public boolean isLocal() {
				return false;
			}

			@Override
			public boolean isMigrationCandidate() throws CoreException {
				return false;
			}

			@Override
			public boolean isReadOnly() {
				return false;
			}

			@Override
			public boolean isWorkingCopy() {
				return false;
			}

			@Override
			public ILaunch launch(String mode, IProgressMonitor monitor)
					throws CoreException {
				return null;
			}

			@Override
			public ILaunch launch(String mode, IProgressMonitor monitor,
					boolean build) throws CoreException {
				return null;
			}

			@Override
			public ILaunch launch(String mode, IProgressMonitor monitor,
					boolean build, boolean register) throws CoreException {
				return null;
			}

			@Override
			public void migrate() throws CoreException {

			}

			@Override
			public boolean supportsMode(String mode) throws CoreException {
				return false;
			}

			@Override
			public <T> T getAdapter(Class<T> adapter) {
				return null;
			}

			@Override
			public boolean hasAttribute(String attributeName)
					throws CoreException {
				return false;
			}
		};
	}

	protected void configureEnvironment(Map<?, ?> env) {
	}

	public IInterpreterInstall[] searchInstalls(String natureId) {
		final List<IInterpreterInstall> installs = new ArrayList<IInterpreterInstall>();
		final InterpreterSearcher searcher = new InterpreterSearcher();

		searcher.search(EnvironmentManager.getLocalEnvironment(), natureId,
				null, 1, null);

		if (searcher.hasResults()) {
			IFileHandle[] files = searcher.getFoundFiles();
			IInterpreterInstallType[] types = searcher.getFoundInstallTypes();

			for (int i = 0; i < files.length; ++i) {
				final IFileHandle file = files[i];
				final IInterpreterInstallType type = types[i];

				// // Skip useless interpreters
				// if (!isInterpreterRequired(file))
				// continue;

				String installId = getNatureId() + "_" + Integer.toString(i);
				IInterpreterInstall install = type
						.findInterpreterInstall(installId);

				if (install == null)
					install = type.createInterpreterInstall(installId);

				install.setName(file.toString());
				install.setInstallLocation(file);
				install.setLibraryLocations(null);
				install.setEnvironmentVariables(null);
				installs.add(install);
			}
		}

		return (IInterpreterInstall[]) installs
				.toArray(new IInterpreterInstall[installs.size()]);
	}

	public void internalTestRequiredInterpreterAvailable(String name) {
		assertTrue("Interpreter " + name + " not available",
				isInterpreterAvailable(name));
	}

	private boolean isInterpreterAvailable(String interpreterName) {
		for (int i = 0; i < interpreterInstalls.length; i++) {
			IFileHandle installLocation = interpreterInstalls[i]
					.getInstallLocation();
			if (isRequiredInstall(interpreterName, installLocation)) {
				return true;
			}
		}
		return false;
	}

	private boolean isRequiredInstall(String interpreterName,
			IFileHandle installLocation) {
		String executableName = installLocation.getName();
		if (executableName.startsWith(interpreterName)) {
			return true;
		}
		return false;
	}

	public final static int SKIP_STDOUT_TEST = 1;

	protected void internalTestRun(String name) throws Exception {
		internalTestRun(name, 0);
	}

	protected void internalTestRun(String name, int flags) throws Exception {
		if (interpreterInstalls.length == 0) {
			fail("No interperters found for nature " + getNatureId());
		}

		for (int i = 0; i < interpreterInstalls.length; ++i) {
			final IInterpreterInstall install = interpreterInstalls[i];
			if (!isRequiredInstall(name, install.getInstallLocation())) {
				continue;
			}
			// System.out.println("Interpreter install location (run): "
			// + install.getInstallLocation().toString());

			// InterpretersUpdater updater = new InterpretersUpdater();
			// updater.updateInterpreterSettings(getNatureId(),
			// interpreterInstalls, install);

			final long time = System.currentTimeMillis();
			final String stdoutTest = Long.toString(time) + "_stdout";
			final String stderrTest = Long.toString(time) + "_stderr";

			final ILaunchConfiguration configuration = createLaunchConfiguration(stdoutTest
					+ " " + stderrTest);

			final ILaunch launch = new Launch(configuration,
					ILaunchManager.RUN_MODE, null);

			startLaunch(launch, install);

			IProcess[] processes = launch.getProcesses();
			assertEquals(1, processes.length);

			final IProcess process = processes[0];
			final IStreamsProxy proxy = process.getStreamsProxy();
			assertNotNull(proxy);

			final IStreamMonitor outputMonitor = proxy.getOutputStreamMonitor();
			assertNotNull(outputMonitor);

			final IStreamMonitor errorMonitor = proxy.getErrorStreamMonitor();
			assertNotNull(errorMonitor);

			while (!process.isTerminated()) {
				Thread.sleep(20);
			}

			assertTrue(process.isTerminated());

			final int exitValue = process.getExitValue();
			assertEquals(0, exitValue);

			if ((flags & SKIP_STDOUT_TEST) == 0) {
				final String output = outputMonitor.getContents();
				assertEquals(stdoutTest, output);
			}

			final String error = errorMonitor.getContents();
			assertEquals(stderrTest, error);
			return;
		}
		assertTrue("Requied interpreter are't found" + name, false);
	}

	public static class DebugEventStats implements IDebugEventSetListener {
		private int suspendCount;
		private int resumeCount;
		private int beforeSuspendCount;
		private int beforeResumeCount;
		private int beforeCodeLoaded;
		private int beforeVmStarted;

		public DebugEventStats() {
			this.suspendCount = 0;
			this.resumeCount = 0;
		}

		@Override
		public void handleDebugEvents(DebugEvent[] events) {
			for (int i = 0; i < events.length; ++i) {
				DebugEvent event = events[i];

				final int kind = event.getKind();
				switch (kind) {
				case DebugEvent.RESUME:
					resumeCount += 1;
					break;
				case DebugEvent.SUSPEND:
					suspendCount += 1;
					try {
						final Object source = event.getSource();
						if (source instanceof IScriptStackFrame) {
							((IScriptStackFrame) source).resume();
						} else if (source instanceof IScriptThread) {
							((IScriptThread) source).resume();
						}
					} catch (DebugException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					break;
				case DebugEvent.CREATE:
					break;
				case DebugEvent.TERMINATE:
					break;
				case DebugEvent.CHANGE:
					break;
				case DebugEvent.MODEL_SPECIFIC:
					handleExtendedEvent(event);
					break;
				}
			}
		}

		private void handleExtendedEvent(DebugEvent event) {
			int extendedType = event.getDetail();
			switch (extendedType) {
			case ExtendedDebugEventDetails.BEFORE_VM_STARTED:
				handleBeforeVmStarted((InterpreterConfig) event.getSource());
				break;
			case ExtendedDebugEventDetails.BEFORE_CODE_LOADED:
				handleBeforeCodeLoaded((ScriptDebugTarget) event.getSource());
				break;
			case ExtendedDebugEventDetails.BEFORE_RESUME:
				handleBeforeResume((ScriptThread) event.getSource());
				break;
			case ExtendedDebugEventDetails.BEFORE_SUSPEND:
				handleBeforeSuspend((ScriptThread) event.getSource());
				break;
			}

		}

		private void handleBeforeSuspend(ScriptThread source) {
			beforeSuspendCount++;
		}

		private void handleBeforeResume(ScriptThread source) {
			beforeResumeCount++;
		}

		private void handleBeforeCodeLoaded(ScriptDebugTarget source) {
			beforeCodeLoaded++;
		}

		private void handleBeforeVmStarted(InterpreterConfig source) {
			beforeVmStarted++;
		}

		public void reset() {
			suspendCount = 0;
			resumeCount = 0;
			beforeSuspendCount = 0;
			beforeResumeCount = 0;
			beforeCodeLoaded = 0;
			beforeVmStarted = 0;
		}

		public int getSuspendCount() {
			return suspendCount;
		}

		public int getResumeCount() {
			return resumeCount;
		}

		public int getBeforeSuspendCount() {
			return beforeSuspendCount;
		}

		public int getBeforeResumeCount() {
			return beforeResumeCount;
		}

		public int getBeforeCodeLoaded() {
			return beforeCodeLoaded;
		}

		public int getBeforeVmStarted() {
			return beforeVmStarted;
		}
	}

	public DebugEventStats internalTestDebug(String name) throws Exception {
		if (interpreterInstalls.length == 0) {
			fail("No interperters found for nature " + getNatureId());
		}

		// Debug
		for (int i = 0; i < interpreterInstalls.length; ++i) {
			final IInterpreterInstall install = interpreterInstalls[i];
			if (!isRequiredInstall(name, install.getInstallLocation())) {
				continue;
			}

			DebugEventStats stats = new DebugEventStats();

			DebugPlugin.getDefault().addDebugEventListener(stats);
			// System.out.println("Interperter install location (debug): "
			// + install.getInstallLocation());

			// final InterpretersUpdater updater = new InterpretersUpdater();
			// updater.updateInterpreterSettings(getNatureId(),
			// interpreterInstalls, install);

			stats.reset();

			final ILaunch launch = new Launch(createLaunchConfiguration(""),
					ILaunchManager.DEBUG_MODE, null);

			// Setting breakpoint
			IFile file = launch.getLaunchConfiguration().getFile();
			IScriptLineBreakpoint b = new ScriptLineBreakpoint(
					getDebugModelId(), file, file.getLocation(), 1, -1, -1,
					true);

			try {
				startLaunch(launch, install);

				IProcess[] processes = launch.getProcesses();
				assertEquals(1, processes.length);

				final IProcess process = processes[0];
				while (!process.isTerminated()) {
					Thread.sleep(200);
				}

				assertTrue(process.isTerminated());
				final int exitValue = process.getExitValue();
				assertEquals(0, exitValue);
			} finally {
				b.delete();

			}
			DebugPlugin.getDefault().removeDebugEventListener(stats);
			return stats;
		}

		fail("Requied interpreter \"" + name + "\" is not found");
		return null;
	}

	protected abstract String getProjectName();

	protected abstract String getNatureId();

	protected abstract String getDebugModelId();

	protected abstract void startLaunch(ILaunch launch,
			final IInterpreterInstall install) throws CoreException;

	protected abstract ILaunchConfiguration createLaunchConfiguration(
			String arguments);

	protected boolean hasPredefinedInterpreters() {
		return false;
	}

	protected IInterpreterInstall createInstall(String path, String id,
			IInterpreterInstallType type) {
		IFileHandle file = EnvironmentManager.getLocalEnvironment().getFile(
				new Path(path));
		if (!file.exists()) {
			return null;
		}
		IInterpreterInstall install = type.findInterpreterInstall(id);

		if (install == null)
			install = type.createInterpreterInstall(id);

		install.setName("");
		install.setInstallLocation(file);
		install.setLibraryLocations(null);
		install.setEnvironmentVariables(null);
		return install;
	}

	protected void createAddInstall(List<IInterpreterInstall> installs, String path, String id,
			IInterpreterInstallType type) {
		IInterpreterInstall install = createInstall(path, id, type);
		if (install != null) {
			installs.add(install);
		}
	}
}
