package consulo.dotnet.debugger;

import java.util.Collection;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.concurrency.AsyncPromise;
import org.jetbrains.concurrency.Promise;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.util.Computable;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XSuspendContext;
import consulo.dotnet.debugger.breakpoint.DotNetExceptionBreakpointType;
import consulo.dotnet.debugger.breakpoint.DotNetLineBreakpointType;
import consulo.dotnet.debugger.breakpoint.DotNetMethodBreakpointType;
import consulo.dotnet.debugger.breakpoint.properties.DotNetExceptionBreakpointProperties;
import consulo.dotnet.debugger.breakpoint.properties.DotNetLineBreakpointProperties;
import consulo.dotnet.debugger.breakpoint.properties.DotNetMethodBreakpointProperties;
import consulo.dotnet.debugger.proxy.DotNetVirtualMachineProxy;

/**
 * @author VISTALL
 * @since 16.04.2016
 */
public abstract class DotNetDebugProcessBase extends XDebugProcess
{
	public static final String RUN_TO_CURSOR = "runToCursor";

	private ExecutionResult myResult;
	private final RunProfile myRunProfile;
	protected final XDebuggerManager myDebuggerManager;

	public DotNetDebugProcessBase(@NotNull XDebugSession session, @NotNull RunProfile runProfile)
	{
		super(session);

		myRunProfile = runProfile;
		myDebuggerManager = XDebuggerManager.getInstance(session.getProject());
	}

	@NotNull
	public DotNetDebugContext createDebugContext(@NotNull DotNetVirtualMachineProxy proxy, @Nullable XBreakpoint<?> breakpoint)
	{
		return new DotNetDebugContext(getSession().getProject(), proxy, myRunProfile, getSession(), breakpoint);
	}

	public abstract void start();

	public void setExecutionResult(ExecutionResult executionResult)
	{
		myResult = executionResult;
	}

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

	@Nullable
	@Override
	protected ProcessHandler doGetProcessHandler()
	{
		return myResult.getProcessHandler();
	}

	@NotNull
	@Override
	public ExecutionConsole createConsole()
	{
		return myResult.getExecutionConsole();
	}

	@NotNull
	@Override
	public XDebuggerEditorsProvider getEditorsProvider()
	{
		return new DotNetEditorsProvider(getSession());
	}

	@Override
	public void startStepOver(@Nullable XSuspendContext context)
	{

	}

	@Override
	public void startStepInto(@Nullable XSuspendContext context)
	{

	}

	@Override
	public void startStepOut(@Nullable XSuspendContext context)
	{

	}

	@Override
	public void resume(@Nullable XSuspendContext context)
	{

	}

	@Override
	public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context)
	{
	}

	@NotNull
	@Override
	public Promise stopAsync()
	{
		AsyncPromise<Boolean> promise = new AsyncPromise<>();
		Task.Backgroundable.queue(getSession().getProject(), "Waiting for debugger response...", indicator ->
		{
			stopImpl();
			promise.setResult(Boolean.TRUE);
		});
		return promise;
	}

	protected abstract void stopImpl();

	@NotNull
	public Collection<? extends XLineBreakpoint<?>> getLineBreakpoints()
	{
		return ApplicationManager.getApplication().runReadAction((Computable<Collection<? extends XLineBreakpoint<DotNetLineBreakpointProperties>>>) () -> myDebuggerManager.getBreakpointManager()
				.getBreakpoints(DotNetLineBreakpointType.getInstance()));
	}

	@NotNull
	public Collection<? extends XLineBreakpoint<DotNetMethodBreakpointProperties>> getMethodBreakpoints()
	{
		return ApplicationManager.getApplication().runReadAction((Computable<Collection<? extends XLineBreakpoint<DotNetMethodBreakpointProperties>>>) () -> myDebuggerManager.getBreakpointManager()
				.getBreakpoints(DotNetMethodBreakpointType.getInstance()));
	}

	@NotNull
	public Collection<? extends XBreakpoint<DotNetExceptionBreakpointProperties>> getExceptionBreakpoints()
	{
		return ApplicationManager.getApplication().runReadAction((Computable<Collection<? extends XBreakpoint<DotNetExceptionBreakpointProperties>>>) () -> myDebuggerManager.getBreakpointManager()
				.getBreakpoints(DotNetExceptionBreakpointType.getInstance()));
	}

	public void normalizeBreakpoints()
	{
		for(XLineBreakpoint<?> lineBreakpoint : getLineBreakpoints())
		{
			myDebuggerManager.getBreakpointManager().updateBreakpointPresentation(lineBreakpoint, null, null);
		}
	}
}

@@ -146,97 +146,8 @@
 le;%0A
-import org.jetbrains.concurrency.AsyncPromise;%0Aimport org.jetbrains.concurrency.Promise;%0A
 impo
@@ -454,16 +454,62 @@
 s.Task;%0A
+import com.intellij.openapi.util.AsyncResult;%0A
 import c
@@ -3309,23 +3309,33 @@
 %09public 
-Promise
+AsyncResult%3CVoid%3E
  stopAsy
@@ -3353,32 +3353,27 @@
 sync
-Promise%3CBoolean%3E promise
+Result%3CVoid%3E result
  = n
@@ -3384,15 +3384,14 @@
 sync
-Promise
+Result
 %3C%3E()
@@ -3522,38 +3522,27 @@
 %0A%09%09%09
-promise.setResult(Boolean.TRUE
+result.setDone(null
 );%0A%09
@@ -3559,15 +3559,14 @@
 urn 
-promise
+result
 ;%0A%09%7D

update to api