/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmDebuggerExceptionManager.h"

#include <utility>
#include <vector>

#include <cm3p/cppdap/optional.h>
#include <cm3p/cppdap/session.h>
#include <cm3p/cppdap/types.h>

#include "cmDebuggerProtocol.h"
#include "cmMessageType.h"

namespace cmDebugger {

cmDebuggerExceptionManager::cmDebuggerExceptionManager(
  dap::Session* dapSession)
  : DapSession(dapSession)
{
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetExceptionBreakpoints
  DapSession->registerHandler(
    [&](const dap::SetExceptionBreakpointsRequest& request) {
      return HandleSetExceptionBreakpointsRequest(request);
    });

  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ExceptionInfo
  DapSession->registerHandler([&](const dap::ExceptionInfoRequest& request) {
    (void)request;
    return HandleExceptionInfoRequest();
  });

  ExceptionMap[MessageType::AUTHOR_WARNING] =
    cmDebuggerExceptionFilter{ "AUTHOR_WARNING", "Warning (dev)" };
  ExceptionMap[MessageType::AUTHOR_ERROR] =
    cmDebuggerExceptionFilter{ "AUTHOR_ERROR", "Error (dev)" };
  ExceptionMap[MessageType::FATAL_ERROR] =
    cmDebuggerExceptionFilter{ "FATAL_ERROR", "Fatal error" };
  ExceptionMap[MessageType::INTERNAL_ERROR] =
    cmDebuggerExceptionFilter{ "INTERNAL_ERROR", "Internal error" };
  ExceptionMap[MessageType::MESSAGE] =
    cmDebuggerExceptionFilter{ "MESSAGE", "Other messages" };
  ExceptionMap[MessageType::WARNING] =
    cmDebuggerExceptionFilter{ "WARNING", "Warning" };
  ExceptionMap[MessageType::LOG] =
    cmDebuggerExceptionFilter{ "LOG", "Debug log" };
  ExceptionMap[MessageType::DEPRECATION_ERROR] =
    cmDebuggerExceptionFilter{ "DEPRECATION_ERROR", "Deprecation error" };
  ExceptionMap[MessageType::DEPRECATION_WARNING] =
    cmDebuggerExceptionFilter{ "DEPRECATION_WARNING", "Deprecation warning" };
  RaiseExceptions["AUTHOR_ERROR"] = true;
  RaiseExceptions["FATAL_ERROR"] = true;
  RaiseExceptions["INTERNAL_ERROR"] = true;
  RaiseExceptions["DEPRECATION_ERROR"] = true;
}

dap::SetExceptionBreakpointsResponse
cmDebuggerExceptionManager::HandleSetExceptionBreakpointsRequest(
  dap::SetExceptionBreakpointsRequest const& request)
{
  std::unique_lock<std::mutex> lock(Mutex);
  dap::SetExceptionBreakpointsResponse response;
  RaiseExceptions.clear();
  for (const auto& filter : request.filters) {
    RaiseExceptions[filter] = true;
  }

  return response;
}

dap::ExceptionInfoResponse
cmDebuggerExceptionManager::HandleExceptionInfoRequest()
{
  std::unique_lock<std::mutex> lock(Mutex);

  dap::ExceptionInfoResponse response;
  if (TheException.has_value()) {
    response.exceptionId = TheException->Id;
    response.breakMode = "always";
    response.description = TheException->Description;
    TheException = cm::nullopt;
  }
  return response;
}

void cmDebuggerExceptionManager::HandleInitializeRequest(
  dap::CMakeInitializeResponse& response)
{
  std::unique_lock<std::mutex> lock(Mutex);
  response.supportsExceptionInfoRequest = true;

  dap::array<dap::ExceptionBreakpointsFilter> exceptionBreakpointFilters;
  for (auto& pair : ExceptionMap) {
    dap::ExceptionBreakpointsFilter filter;
    filter.filter = pair.second.Filter;
    filter.label = pair.second.Label;
    filter.def = RaiseExceptions[filter.filter];
    exceptionBreakpointFilters.emplace_back(filter);
  }

  response.exceptionBreakpointFilters = exceptionBreakpointFilters;
}

cm::optional<dap::StoppedEvent>
cmDebuggerExceptionManager::RaiseExceptionIfAny(MessageType t,
                                                std::string const& text)
{
  cm::optional<dap::StoppedEvent> maybeStoppedEvent;
  std::unique_lock<std::mutex> lock(Mutex);
  if (RaiseExceptions[ExceptionMap[t].Filter]) {
    dap::StoppedEvent stoppedEvent;
    stoppedEvent.allThreadsStopped = true;
    stoppedEvent.reason = "exception";
    stoppedEvent.description = "Pause on exception";
    stoppedEvent.text = text;
    TheException = cmDebuggerException{ ExceptionMap[t].Filter, text };
    maybeStoppedEvent = std::move(stoppedEvent);
  }

  return maybeStoppedEvent;
}

void cmDebuggerExceptionManager::ClearAll()
{
  std::unique_lock<std::mutex> lock(Mutex);
  RaiseExceptions.clear();
}

} // namespace cmDebugger
