//===--- DraftStore.cpp - File contents container ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DraftStore.h"
#include "Logger.h"
#include "SourceCode.h"
#include "llvm/Support/Errc.h"

namespace clang {
namespace clangd {

llvm::Optional<DraftStore::Draft> DraftStore::getDraft(PathRef File) const {
  std::lock_guard<std::mutex> Lock(Mutex);

  auto It = Drafts.find(File);
  if (It == Drafts.end())
    return None;

  return It->second;
}

std::vector<Path> DraftStore::getActiveFiles() const {
  std::lock_guard<std::mutex> Lock(Mutex);
  std::vector<Path> ResultVector;

  for (auto DraftIt = Drafts.begin(); DraftIt != Drafts.end(); DraftIt++)
    ResultVector.push_back(std::string(DraftIt->getKey()));

  return ResultVector;
}

static void updateVersion(DraftStore::Draft &D,
                          llvm::Optional<int64_t> Version) {
  if (Version) {
    // We treat versions as opaque, but the protocol says they increase.
    if (*Version <= D.Version)
      log("File version went from {0} to {1}", D.Version, Version);
    D.Version = *Version;
  } else {
    // Note that if D was newly-created, this will bump D.Version from -1 to 0.
    ++D.Version;
  }
}

int64_t DraftStore::addDraft(PathRef File, llvm::Optional<int64_t> Version,
                         llvm::StringRef Contents) {
  std::lock_guard<std::mutex> Lock(Mutex);

  Draft &D = Drafts[File];
  updateVersion(D, Version);
  D.Contents = Contents.str();
  return D.Version;
}

llvm::Expected<DraftStore::Draft> DraftStore::updateDraft(
    PathRef File, llvm::Optional<int64_t> Version,
    llvm::ArrayRef<TextDocumentContentChangeEvent> Changes) {
  std::lock_guard<std::mutex> Lock(Mutex);

  auto EntryIt = Drafts.find(File);
  if (EntryIt == Drafts.end()) {
    return llvm::make_error<llvm::StringError>(
        "Trying to do incremental update on non-added document: " + File,
        llvm::errc::invalid_argument);
  }
  Draft &D = EntryIt->second;
  std::string Contents = EntryIt->second.Contents;

  for (const TextDocumentContentChangeEvent &Change : Changes) {
    if (!Change.range) {
      Contents = Change.text;
      continue;
    }

    const Position &Start = Change.range->start;
    llvm::Expected<size_t> StartIndex =
        positionToOffset(Contents, Start, false);
    if (!StartIndex)
      return StartIndex.takeError();

    const Position &End = Change.range->end;
    llvm::Expected<size_t> EndIndex = positionToOffset(Contents, End, false);
    if (!EndIndex)
      return EndIndex.takeError();

    if (*EndIndex < *StartIndex)
      return llvm::make_error<llvm::StringError>(
          llvm::formatv(
              "Range's end position ({0}) is before start position ({1})", End,
              Start),
          llvm::errc::invalid_argument);

    // Since the range length between two LSP positions is dependent on the
    // contents of the buffer we compute the range length between the start and
    // end position ourselves and compare it to the range length of the LSP
    // message to verify the buffers of the client and server are in sync.

    // EndIndex and StartIndex are in bytes, but Change.rangeLength is in UTF-16
    // code units.
    ssize_t ComputedRangeLength =
        lspLength(Contents.substr(*StartIndex, *EndIndex - *StartIndex));

    if (Change.rangeLength && ComputedRangeLength != *Change.rangeLength)
      return llvm::make_error<llvm::StringError>(
          llvm::formatv("Change's rangeLength ({0}) doesn't match the "
                        "computed range length ({1}).",
                        *Change.rangeLength, ComputedRangeLength),
          llvm::errc::invalid_argument);

    std::string NewContents;
    NewContents.reserve(*StartIndex + Change.text.length() +
                        (Contents.length() - *EndIndex));

    NewContents = Contents.substr(0, *StartIndex);
    NewContents += Change.text;
    NewContents += Contents.substr(*EndIndex);

    Contents = std::move(NewContents);
  }

  updateVersion(D, Version);
  D.Contents = std::move(Contents);
  return D;
}

void DraftStore::removeDraft(PathRef File) {
  std::lock_guard<std::mutex> Lock(Mutex);

  Drafts.erase(File);
}

} // namespace clangd
} // namespace clang
