//===--- 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;
  Intent intent() const override { return Intent::Refactor; }

  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 = 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 llvm::formatv("Expand macro '{0}'", MacroName);
}

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