// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// hello_debugger is an example DAP server that provides single line stepping
// through a synthetic file.

#include "dap/io.h"
#include "dap/protocol.h"
#include "dap/session.h"

#include <condition_variable>
#include <cstdio>
#include <mutex>
#include <unordered_set>

#ifdef _MSC_VER
#define OS_WINDOWS 1
#endif

// Uncomment the line below and change <path-to-log-file> to a file path to
// write all DAP communications to the given path.
//
// #define LOG_TO_FILE "<path-to-log-file>"

#ifdef OS_WINDOWS
#include <fcntl.h>  // _O_BINARY
#include <io.h>     // _setmode
#endif              // OS_WINDOWS

namespace {

// sourceContent holds the synthetic file source.
constexpr char sourceContent[] = R"(// Hello Debugger!

This is a synthetic source file provided by the DAP debugger.

You can set breakpoints, and single line step.

You may also notice that the locals contains a single variable for the currently executing line number.)";

// Total number of newlines in source.
constexpr int numSourceLines = 7;

// Debugger holds the dummy debugger state and fires events to the EventHandler
// passed to the constructor.
class Debugger {
 public:
  enum class Event { BreakpointHit, Stepped, Paused };
  using EventHandler = std::function<void(Event)>;

  Debugger(const EventHandler&);

  // run() instructs the debugger to continue execution.
  void run();

  // pause() instructs the debugger to pause execution.
  void pause();

  // currentLine() returns the currently executing line number.
  int currentLine();

  // stepForward() instructs the debugger to step forward one line.
  void stepForward();

  // clearBreakpoints() clears all set breakpoints.
  void clearBreakpoints();

  // addBreakpoint() sets a new breakpoint on the given line.
  void addBreakpoint(int line);

 private:
  EventHandler onEvent;
  std::mutex mutex;
  int line = 1;
  std::unordered_set<int> breakpoints;
};

Debugger::Debugger(const EventHandler& onEvent) : onEvent(onEvent) {}

void Debugger::run() {
  std::unique_lock<std::mutex> lock(mutex);
  for (int i = 0; i < numSourceLines; i++) {
    auto l = ((line + i) % numSourceLines) + 1;
    if (breakpoints.count(l)) {
      line = l;
      lock.unlock();
      onEvent(Event::BreakpointHit);
      return;
    }
  }
}

void Debugger::pause() {
  onEvent(Event::Paused);
}

int Debugger::currentLine() {
  std::unique_lock<std::mutex> lock(mutex);
  return line;
}

void Debugger::stepForward() {
  std::unique_lock<std::mutex> lock(mutex);
  line = (line % numSourceLines) + 1;
  lock.unlock();
  onEvent(Event::Stepped);
}

void Debugger::clearBreakpoints() {
  std::unique_lock<std::mutex> lock(mutex);
  this->breakpoints.clear();
}

void Debugger::addBreakpoint(int l) {
  std::unique_lock<std::mutex> lock(mutex);
  this->breakpoints.emplace(l);
}

// Event provides a basic wait and signal synchronization primitive.
class Event {
 public:
  // wait() blocks until the event is fired.
  void wait();

  // fire() sets signals the event, and unblocks any calls to wait().
  void fire();

 private:
  std::mutex mutex;
  std::condition_variable cv;
  bool fired = false;
};

void Event::wait() {
  std::unique_lock<std::mutex> lock(mutex);
  cv.wait(lock, [&] { return fired; });
}

void Event::fire() {
  std::unique_lock<std::mutex> lock(mutex);
  fired = true;
  cv.notify_all();
}

}  // anonymous namespace

// main() entry point to the DAP server.
int main(int, char* []) {
#ifdef OS_WINDOWS
  // Change stdin & stdout from text mode to binary mode.
  // This ensures sequences of \r\n are not changed to \n.
  _setmode(_fileno(stdin), _O_BINARY);
  _setmode(_fileno(stdout), _O_BINARY);
#endif  // OS_WINDOWS

  std::shared_ptr<dap::Writer> log;
#ifdef LOG_TO_FILE
  log = dap::file(LOG_TO_FILE);
#endif

  // Create the DAP session.
  // This is used to implement the DAP server.
  auto session = dap::Session::create();

  // Hard-coded identifiers for the one thread, frame, variable and source.
  // These numbers have no meaning, and just need to remain constant for the
  // duration of the service.
  const dap::integer threadId = 100;
  const dap::integer frameId = 200;
  const dap::integer variablesReferenceId = 300;
  const dap::integer sourceReferenceId = 400;

  // Signal events
  Event configured;
  Event terminate;

  // Event handlers from the Debugger.
  auto onDebuggerEvent = [&](Debugger::Event onEvent) {
    switch (onEvent) {
      case Debugger::Event::Stepped: {
        // The debugger has single-line stepped. Inform the client.
        dap::StoppedEvent event;
        event.reason = "step";
        event.threadId = threadId;
        session->send(event);
        break;
      }
      case Debugger::Event::BreakpointHit: {
        // The debugger has hit a breakpoint. Inform the client.
        dap::StoppedEvent event;
        event.reason = "breakpoint";
        event.threadId = threadId;
        session->send(event);
        break;
      }
      case Debugger::Event::Paused: {
        // The debugger has been suspended. Inform the client.
        dap::StoppedEvent event;
        event.reason = "pause";
        event.threadId = threadId;
        session->send(event);
        break;
      }
    }
  };

  // Construct the debugger.
  Debugger debugger(onDebuggerEvent);

  // Handle errors reported by the Session. These errors include protocol
  // parsing errors and receiving messages with no handler.
  session->onError([&](const char* msg) {
    if (log) {
      dap::writef(log, "dap::Session error: %s\n", msg);
      log->close();
    }
    terminate.fire();
  });

  // The Initialize request is the first message sent from the client and
  // the response reports debugger capabilities.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Initialize
  session->registerHandler([](const dap::InitializeRequest&) {
    dap::InitializeResponse response;
    response.supportsConfigurationDoneRequest = true;
    return response;
  });

  // When the Initialize response has been sent, we need to send the initialized
  // event.
  // We use the registerSentHandler() to ensure the event is sent *after* the
  // initialize response.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Events_Initialized
  session->registerSentHandler(
      [&](const dap::ResponseOrError<dap::InitializeResponse>&) {
        session->send(dap::InitializedEvent());
      });

  // The Threads request queries the debugger's list of active threads.
  // This example debugger only exposes a single thread.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Threads
  session->registerHandler([&](const dap::ThreadsRequest&) {
    dap::ThreadsResponse response;
    dap::Thread thread;
    thread.id = threadId;
    thread.name = "TheThread";
    response.threads.push_back(thread);
    return response;
  });

  // The StackTrace request reports the stack frames (call stack) for a given
  // thread. This example debugger only exposes a single stack frame for the
  // single thread.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_StackTrace
  session->registerHandler(
      [&](const dap::StackTraceRequest& request)
          -> dap::ResponseOrError<dap::StackTraceResponse> {
        if (request.threadId != threadId) {
          return dap::Error("Unknown threadId '%d'", int(request.threadId));
        }

        dap::Source source;
        source.sourceReference = sourceReferenceId;
        source.name = "HelloDebuggerSource";

        dap::StackFrame frame;
        frame.line = debugger.currentLine();
        frame.column = 1;
        frame.name = "HelloDebugger";
        frame.id = frameId;
        frame.source = source;

        dap::StackTraceResponse response;
        response.stackFrames.push_back(frame);
        return response;
      });

  // The Scopes request reports all the scopes of the given stack frame.
  // This example debugger only exposes a single 'Locals' scope for the single
  // frame.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Scopes
  session->registerHandler([&](const dap::ScopesRequest& request)
                               -> dap::ResponseOrError<dap::ScopesResponse> {
    if (request.frameId != frameId) {
      return dap::Error("Unknown frameId '%d'", int(request.frameId));
    }

    dap::Scope scope;
    scope.name = "Locals";
    scope.presentationHint = "locals";
    scope.variablesReference = variablesReferenceId;

    dap::ScopesResponse response;
    response.scopes.push_back(scope);
    return response;
  });

  // The Variables request reports all the variables for the given scope.
  // This example debugger only exposes a single 'currentLine' variable for the
  // single 'Locals' scope.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Variables
  session->registerHandler([&](const dap::VariablesRequest& request)
                               -> dap::ResponseOrError<dap::VariablesResponse> {
    if (request.variablesReference != variablesReferenceId) {
      return dap::Error("Unknown variablesReference '%d'",
                        int(request.variablesReference));
    }

    dap::Variable currentLineVar;
    currentLineVar.name = "currentLine";
    currentLineVar.value = std::to_string(debugger.currentLine());
    currentLineVar.type = "int";

    dap::VariablesResponse response;
    response.variables.push_back(currentLineVar);
    return response;
  });

  // The Pause request instructs the debugger to pause execution of one or all
  // threads.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Pause
  session->registerHandler([&](const dap::PauseRequest&) {
    debugger.pause();
    return dap::PauseResponse();
  });

  // The Continue request instructs the debugger to resume execution of one or
  // all threads.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Continue
  session->registerHandler([&](const dap::ContinueRequest&) {
    debugger.run();
    return dap::ContinueResponse();
  });

  // The Next request instructs the debugger to single line step for a specific
  // thread.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Next
  session->registerHandler([&](const dap::NextRequest&) {
    debugger.stepForward();
    return dap::NextResponse();
  });

  // The StepIn request instructs the debugger to step-in for a specific thread.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_StepIn
  session->registerHandler([&](const dap::StepInRequest&) {
    // Step-in treated as step-over as there's only one stack frame.
    debugger.stepForward();
    return dap::StepInResponse();
  });

  // The StepOut request instructs the debugger to step-out for a specific
  // thread.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_StepOut
  session->registerHandler([&](const dap::StepOutRequest&) {
    // Step-out is not supported as there's only one stack frame.
    return dap::StepOutResponse();
  });

  // The SetBreakpoints request instructs the debugger to clear and set a number
  // of line breakpoints for a specific source file.
  // This example debugger only exposes a single source file.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetBreakpoints
  session->registerHandler([&](const dap::SetBreakpointsRequest& request) {
    dap::SetBreakpointsResponse response;

    auto breakpoints = request.breakpoints.value({});
    if (request.source.sourceReference.value(0) == sourceReferenceId) {
      debugger.clearBreakpoints();
      response.breakpoints.resize(breakpoints.size());
      for (size_t i = 0; i < breakpoints.size(); i++) {
        debugger.addBreakpoint(breakpoints[i].line);
        response.breakpoints[i].verified = breakpoints[i].line < numSourceLines;
      }
    } else {
      response.breakpoints.resize(breakpoints.size());
    }

    return response;
  });

  // The SetExceptionBreakpoints request configures the debugger's handling of
  // thrown exceptions.
  // This example debugger does not use any exceptions, so this is a no-op.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetExceptionBreakpoints
  session->registerHandler([&](const dap::SetExceptionBreakpointsRequest&) {
    return dap::SetExceptionBreakpointsResponse();
  });

  // The Source request retrieves the source code for a given source file.
  // This example debugger only exposes one synthetic source file.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Source
  session->registerHandler([&](const dap::SourceRequest& request)
                               -> dap::ResponseOrError<dap::SourceResponse> {
    if (request.sourceReference != sourceReferenceId) {
      return dap::Error("Unknown source reference '%d'",
                        int(request.sourceReference));
    }

    dap::SourceResponse response;
    response.content = sourceContent;
    return response;
  });

  // The Launch request is made when the client instructs the debugger adapter
  // to start the debuggee. This request contains the launch arguments.
  // This example debugger does nothing with this request.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Launch
  session->registerHandler(
      [&](const dap::LaunchRequest&) { return dap::LaunchResponse(); });

  // Handler for disconnect requests
  session->registerHandler([&](const dap::DisconnectRequest& request) {
    if (request.terminateDebuggee.value(false)) {
      terminate.fire();
    }
    return dap::DisconnectResponse();
  });

  // The ConfigurationDone request is made by the client once all configuration
  // requests have been made.
  // This example debugger uses this request to 'start' the debugger.
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ConfigurationDone
  session->registerHandler([&](const dap::ConfigurationDoneRequest&) {
    configured.fire();
    return dap::ConfigurationDoneResponse();
  });

  // All the handlers we care about have now been registered.
  // We now bind the session to stdin and stdout to connect to the client.
  // After the call to bind() we should start receiving requests, starting with
  // the Initialize request.
  std::shared_ptr<dap::Reader> in = dap::file(stdin, false);
  std::shared_ptr<dap::Writer> out = dap::file(stdout, false);
  if (log) {
    session->bind(spy(in, log), spy(out, log));
  } else {
    session->bind(in, out);
  }

  // Wait for the ConfigurationDone request to be made.
  configured.wait();

  // Broadcast the existance of the single thread to the client.
  dap::ThreadEvent threadStartedEvent;
  threadStartedEvent.reason = "started";
  threadStartedEvent.threadId = threadId;
  session->send(threadStartedEvent);

  // Start the debugger in a paused state.
  // This sends a stopped event to the client.
  debugger.pause();

  // Block until we receive a 'terminateDebuggee' request or encounter a session
  // error.
  terminate.wait();

  return 0;
}
