import { DebugProtocol } from "@vscode/debugprotocol";
import { Debugger } from "./debugger";
import { Command } from "./types";

export async function handle_request(request: DebugProtocol.Request): Promise<DebugProtocol.Response> {
  const debugger_instance: Debugger = Debugger.Instance;
  if (request.command !== Command.Initialize && !debugger_instance.initialized) {
    throw new Error(`Debugger is not initialized, request: ${request}`);
  }
  let body: any = null;
  return new Promise(async (resolve, _) => {
    switch (request.command) {
      case Command.Initialize:
        await debugger_instance.initialize(request.arguments);
        break;
      case Command.Reset:
        await debugger_instance.reset();
        body = debugger_instance.currentLocation();
        break;
      case Command.StepInto:
        await debugger_instance.stepInto();
        body = debugger_instance.currentLocation();
        break;
      case Command.StepNext:
        await debugger_instance.stepNext();
        body = debugger_instance.currentLocation();
        break;
      case Command.StepOut:
        await debugger_instance.stepOut();
        body = debugger_instance.currentLocation();
        break;
      case Command.StepInstruction:
        await debugger_instance.advance();
        body = debugger_instance.currentLocation();
        break;
      case Command.StepOver:
        await debugger_instance.stepOver();
        body = debugger_instance.currentLocation();
        break;
      case Command.AddBreakpoint:
        await debugger_instance.addBreakpoint(request.arguments);
        break;
      case Command.RemoveBreakpoint:
        await debugger_instance.removeBreakpoint(request.arguments);
        break;
      case Command.RemoveAllBreakpoints:
        await debugger_instance.removeAllBreakpoints();
        break;
      case Command.ContinueUntilBreakpoint:
        await debugger_instance.continueUntilBreakpoint();
        body = debugger_instance.currentLocation();
        break;
      case Command.Variables:
        body = await debugger_instance.variables();
        break;
      case Command.Stacktrace:
        body = debugger_instance.stackTrace();
        break;
      default:
        break;
    }
    resolve({
      command: request.command,
      request_seq: request.seq,
      success: true,
      body: body,
      seq: request.seq,
      type: 'response'
    });
  });
}