//===--- ExpandMacro.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 "refactor/Tweak.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Syntax/Tokens.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
#include <string>
namespace clang {
namespace clangd {
namespace {

/// Replaces a reference to a macro under the cursor with its expansion.
/// Before:
///   #define FOO(X) X+X
///   FOO(10*a)
///   ^^^
/// After:
///   #define FOO(X) X+X
///   10*a+10*a
class ExpandMacro : public Tweak {
public:
  const char *id() const override final;
  llvm::StringLiteral kind() const override {
    return CodeAction::REFACTOR_KIND;
  }

  bool prepare(const Selection &Inputs) override;
  Expected<Tweak::Effect> apply(const Selection &Inputs) override;
  std::string title() const override;

private:
  syntax::TokenBuffer::Expansion Expansion;
  std::string MacroName;
};

REGISTER_TWEAK(ExpandMacro)

/// Finds a spelled token that the cursor is pointing at.
static const syntax::Token *
findTokenUnderCursor(const SourceManager &SM,
                     llvm::ArrayRef<syntax::Token> Spelled,
                     unsigned CursorOffset) {
  // Find the token that strats after the offset, then look at a previous one.
  auto It = llvm::partition_point(Spelled, [&](const syntax::Token &T) {
    assert(T.location().isFileID());
    return SM.getFileOffset(T.location()) <= CursorOffset;
  });
  if (It == Spelled.begin())
    return nullptr;
  // Check the token we found actually touches the cursor position.
  --It;
  return It->range(SM).touches(CursorOffset) ? It : nullptr;
}

static const syntax::Token *
findIdentifierUnderCursor(const syntax::TokenBuffer &Tokens,
                          SourceLocation Cursor) {
  assert(Cursor.isFileID());

  auto &SM = Tokens.sourceManager();
  auto Spelled = Tokens.spelledTokens(SM.getFileID(Cursor));

  auto *T = findTokenUnderCursor(SM, Spelled, SM.getFileOffset(Cursor));
  if (!T)
    return nullptr;
  if (T->kind() == tok::identifier)
    return T;
  // Also try the previous token when the cursor is at the boundary, e.g.
  //   FOO^()
  //   FOO^+
  if (T == Spelled.begin())
    return nullptr;
  --T;
  if (T->endLocation() != Cursor || T->kind() != tok::identifier)
    return nullptr;
  return T;
}

bool ExpandMacro::prepare(const Selection &Inputs) {
  // FIXME: we currently succeed on selection at the end of the token, e.g.
  //        'FOO[[ ]]BAR'. We should not trigger in that case.

  // Find a token under the cursor.
  auto *T = findIdentifierUnderCursor(Inputs.AST->getTokens(), Inputs.Cursor);
  // We are interested only in identifiers, other tokens can't be macro names.
  if (!T)
    return false;
  // If the identifier is a macro we will find the corresponding expansion.
  auto Expansion = Inputs.AST->getTokens().expansionStartingAt(T);
  if (!Expansion)
    return false;
  this->MacroName = std::string(T->text(Inputs.AST->getSourceManager()));
  this->Expansion = *Expansion;
  return true;
}

Expected<Tweak::Effect> ExpandMacro::apply(const Selection &Inputs) {
  auto &SM = Inputs.AST->getSourceManager();

  std::string Replacement;
  for (const syntax::Token &T : Expansion.Expanded) {
    Replacement += T.text(SM);
    Replacement += " ";
  }
  if (!Replacement.empty()) {
    assert(Replacement.back() == ' ');
    Replacement.pop_back();
  }

  CharSourceRange MacroRange =
      CharSourceRange::getCharRange(Expansion.Spelled.front().location(),
                                    Expansion.Spelled.back().endLocation());

  tooling::Replacements Reps;
  llvm::cantFail(Reps.add(tooling::Replacement(SM, MacroRange, Replacement)));
  return Effect::mainFileEdit(SM, std::move(Reps));
}

std::string ExpandMacro::title() const {
  return std::string(llvm::formatv("Expand macro '{0}'", MacroName));
}

} // namespace
} // namespace clangd
} // namespace clang
