//===-- CompletionRequest.cpp -----------------------------------*- 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 "lldb/Utility/CompletionRequest.h"

using namespace lldb;
using namespace lldb_private;

CompletionRequest::CompletionRequest(llvm::StringRef command_line,
                                     unsigned raw_cursor_pos,
                                     CompletionResult &result)
    : m_command(command_line), m_raw_cursor_pos(raw_cursor_pos),
      m_result(result) {
  assert(raw_cursor_pos <= command_line.size() && "Out of bounds cursor?");

  // We parse the argument up to the cursor, so the last argument in
  // parsed_line is the one containing the cursor, and the cursor is after the
  // last character.
  m_parsed_line = Args(command_line);
  m_partial_parsed_line = Args(command_line.substr(0, raw_cursor_pos));

  m_cursor_index = m_partial_parsed_line.GetArgumentCount() - 1;

  if (m_cursor_index == -1)
    m_cursor_char_position = 0;
  else
    m_cursor_char_position =
        strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index));

  const char *cursor = command_line.data() + raw_cursor_pos;
  if (raw_cursor_pos > 0 && cursor[-1] == ' ') {
    // We are just after a space.  If we are in an argument, then we will
    // continue parsing, but if we are between arguments, then we have to
    // complete whatever the next element would be. We can distinguish the two
    // cases because if we are in an argument (e.g. because the space is
    // protected by a quote) then the space will also be in the parsed
    // argument...

    const char *current_elem =
        m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index);
    if (m_cursor_char_position == 0 ||
        current_elem[m_cursor_char_position - 1] != ' ') {
      m_parsed_line.InsertArgumentAtIndex(m_cursor_index + 1, llvm::StringRef(),
                                          '\0');
      m_cursor_index++;
      m_cursor_char_position = 0;
    }
  }
}

std::string CompletionResult::Completion::GetUniqueKey() const {

  // We build a unique key for this pair of completion:description. We
  // prefix the key with the length of the completion string. This prevents
  // that we could get any collisions from completions pairs such as these:
  // "foo:", "bar" would be "foo:bar", but will now be: "4foo:bar"
  // "foo", ":bar" would be "foo:bar", but will now be: "3foo:bar"

  std::string result;
  result.append(std::to_string(m_completion.size()));
  result.append(m_completion);
  result.append(m_descripton);
  return result;
}

void CompletionResult::AddResult(llvm::StringRef completion,
                                 llvm::StringRef description) {
  Completion r(completion, description);

  // Add the completion if we haven't seen the same value before.
  if (m_added_values.insert(r.GetUniqueKey()).second)
    m_results.push_back(r);
}

void CompletionResult::GetMatches(StringList &matches) const {
  matches.Clear();
  for (const Completion &completion : m_results)
    matches.AppendString(completion.m_completion);
}

void CompletionResult::GetDescriptions(StringList &descriptions) const {
  descriptions.Clear();
  for (const Completion &completion : m_results)
    descriptions.AppendString(completion.m_descripton);
}
