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

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <utility>

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

#include "cmDebuggerSourceBreakpoint.h"
#include "cmListFileCache.h"
#include "cmSystemTools.h"

namespace cmDebugger {

cmDebuggerBreakpointManager::cmDebuggerBreakpointManager(
  dap::Session* dapSession)
  : DapSession(dapSession)
{
  // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetBreakpoints
  DapSession->registerHandler([&](const dap::SetBreakpointsRequest& request) {
    return HandleSetBreakpointsRequest(request);
  });
}

int64_t cmDebuggerBreakpointManager::FindFunctionStartLine(
  std::string const& sourcePath, int64_t line)
{
  auto location =
    find_if(ListFileFunctionLines[sourcePath].begin(),
            ListFileFunctionLines[sourcePath].end(),
            [=](cmDebuggerFunctionLocation const& loc) {
              return loc.StartLine <= line && loc.EndLine >= line;
            });

  if (location != ListFileFunctionLines[sourcePath].end()) {
    return location->StartLine;
  }

  return 0;
}

int64_t cmDebuggerBreakpointManager::CalibrateBreakpointLine(
  std::string const& sourcePath, int64_t line)
{
  auto location = find_if(ListFileFunctionLines[sourcePath].begin(),
                          ListFileFunctionLines[sourcePath].end(),
                          [=](cmDebuggerFunctionLocation const& loc) {
                            return loc.StartLine >= line;
                          });

  if (location != ListFileFunctionLines[sourcePath].end()) {
    return location->StartLine;
  }

  if (!ListFileFunctionLines[sourcePath].empty() &&
      ListFileFunctionLines[sourcePath].back().EndLine <= line) {
    // return last function start line for any breakpoints after.
    return ListFileFunctionLines[sourcePath].back().StartLine;
  }

  return 0;
}

dap::SetBreakpointsResponse
cmDebuggerBreakpointManager::HandleSetBreakpointsRequest(
  dap::SetBreakpointsRequest const& request)
{
  std::unique_lock<std::mutex> lock(Mutex);

  dap::SetBreakpointsResponse response;

  auto sourcePath =
    cmSystemTools::GetActualCaseForPath(request.source.path.value());
  const dap::array<dap::SourceBreakpoint> defaultValue{};
  const auto& breakpoints = request.breakpoints.value(defaultValue);

  if (Breakpoints.find(sourcePath) != Breakpoints.end()) {
    Breakpoints[sourcePath].clear();
  }
  response.breakpoints.resize(breakpoints.size());

  if (ListFileFunctionLines.find(sourcePath) != ListFileFunctionLines.end()) {
    // The file has loaded, we can validate breakpoints.
    for (size_t i = 0; i < breakpoints.size(); i++) {
      int64_t correctedLine =
        CalibrateBreakpointLine(sourcePath, breakpoints[i].line);
      if (correctedLine > 0) {
        Breakpoints[sourcePath].emplace_back(NextBreakpointId++,
                                             correctedLine);
        response.breakpoints[i].id = Breakpoints[sourcePath].back().GetId();
        response.breakpoints[i].line =
          Breakpoints[sourcePath].back().GetLine();
        response.breakpoints[i].verified = true;
      } else {
        response.breakpoints[i].verified = false;
        response.breakpoints[i].line = breakpoints[i].line;
      }
      dap::Source dapSrc;
      dapSrc.path = sourcePath;
      response.breakpoints[i].source = dapSrc;
    }
  } else {
    // The file has not loaded, validate breakpoints later.
    ListFilePendingValidations.emplace(sourcePath);

    for (size_t i = 0; i < breakpoints.size(); i++) {
      Breakpoints[sourcePath].emplace_back(NextBreakpointId++,
                                           breakpoints[i].line);
      response.breakpoints[i].id = Breakpoints[sourcePath].back().GetId();
      response.breakpoints[i].line = Breakpoints[sourcePath].back().GetLine();
      response.breakpoints[i].verified = false;
      dap::Source dapSrc;
      dapSrc.path = sourcePath;
      response.breakpoints[i].source = dapSrc;
    }
  }

  return response;
}

void cmDebuggerBreakpointManager::SourceFileLoaded(
  std::string const& sourcePath,
  std::vector<cmListFileFunction> const& functions)
{
  std::unique_lock<std::mutex> lock(Mutex);
  if (ListFileFunctionLines.find(sourcePath) != ListFileFunctionLines.end()) {
    // this is not expected.
    return;
  }

  for (cmListFileFunction const& func : functions) {
    ListFileFunctionLines[sourcePath].emplace_back(
      cmDebuggerFunctionLocation{ func.Line(), func.LineEnd() });
  }

  if (ListFilePendingValidations.find(sourcePath) ==
      ListFilePendingValidations.end()) {
    return;
  }

  ListFilePendingValidations.erase(sourcePath);

  for (size_t i = 0; i < Breakpoints[sourcePath].size(); i++) {
    dap::BreakpointEvent breakpointEvent;
    breakpointEvent.breakpoint.id = Breakpoints[sourcePath][i].GetId();
    breakpointEvent.breakpoint.line = Breakpoints[sourcePath][i].GetLine();
    auto source = dap::Source();
    source.path = sourcePath;
    breakpointEvent.breakpoint.source = source;
    int64_t correctedLine = CalibrateBreakpointLine(
      sourcePath, Breakpoints[sourcePath][i].GetLine());
    if (correctedLine != Breakpoints[sourcePath][i].GetLine()) {
      Breakpoints[sourcePath][i].ChangeLine(correctedLine);
    }
    breakpointEvent.reason = "changed";
    breakpointEvent.breakpoint.verified = (correctedLine > 0);
    if (breakpointEvent.breakpoint.verified) {
      breakpointEvent.breakpoint.line = correctedLine;
    } else {
      Breakpoints[sourcePath][i].Invalid();
    }

    DapSession->send(breakpointEvent);
  }
}

std::vector<int64_t> cmDebuggerBreakpointManager::GetBreakpoints(
  std::string const& sourcePath, int64_t line)
{
  std::unique_lock<std::mutex> lock(Mutex);
  const auto& all = Breakpoints[sourcePath];
  std::vector<int64_t> breakpoints;
  if (all.empty()) {
    return breakpoints;
  }

  auto it = all.begin();

  while ((it = std::find_if(
            it, all.end(), [&](const cmDebuggerSourceBreakpoint& breakpoint) {
              return (breakpoint.GetIsValid() && breakpoint.GetLine() == line);
            })) != all.end()) {
    breakpoints.emplace_back(it->GetId());
    ++it;
  }

  return breakpoints;
}

size_t cmDebuggerBreakpointManager::GetBreakpointCount() const
{
  size_t count = 0;
  for (auto const& pair : Breakpoints) {
    count += pair.second.size();
  }
  return count;
}

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

} // namespace cmDebugger
