//===--- Stencil.cpp - Stencil implementation -------------------*- 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 "clang/Tooling/Transformer/Stencil.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Expr.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/Transformer/SourceCode.h"
#include "clang/Tooling/Transformer/SourceCodeBuilders.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include <memory>
#include <string>

using namespace clang;
using namespace transformer;

using ast_matchers::BoundNodes;
using ast_matchers::MatchFinder;
using llvm::errc;
using llvm::Error;
using llvm::Expected;
using llvm::StringError;

static llvm::Expected<DynTypedNode> getNode(const BoundNodes &Nodes,
                                            StringRef Id) {
  auto &NodesMap = Nodes.getMap();
  auto It = NodesMap.find(Id);
  if (It == NodesMap.end())
    return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
                                               "Id not bound: " + Id);
  return It->second;
}

static Error printNode(StringRef Id, const MatchFinder::MatchResult &Match,
                       std::string *Result) {
  std::string Output;
  llvm::raw_string_ostream Os(Output);
  auto NodeOrErr = getNode(Match.Nodes, Id);
  if (auto Err = NodeOrErr.takeError())
    return Err;
  const PrintingPolicy PP(Match.Context->getLangOpts());
  if (const auto *ND = NodeOrErr->get<NamedDecl>()) {
    // For NamedDecls, we can do a better job than printing the whole thing.
    ND->getNameForDiagnostic(Os, PP, false);
  } else {
    NodeOrErr->print(Os, PP);
  }
  *Result += Output;
  return Error::success();
}

namespace {
// An arbitrary fragment of code within a stencil.
class RawTextStencil : public StencilInterface {
  std::string Text;

public:
  explicit RawTextStencil(std::string T) : Text(std::move(T)) {}

  std::string toString() const override {
    std::string Result;
    llvm::raw_string_ostream OS(Result);
    OS << "\"";
    OS.write_escaped(Text);
    OS << "\"";
    return Result;
  }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    Result->append(Text);
    return Error::success();
  }
};

// A debugging operation to dump the AST for a particular (bound) AST node.
class DebugPrintNodeStencil : public StencilInterface {
  std::string Id;

public:
  explicit DebugPrintNodeStencil(std::string S) : Id(std::move(S)) {}

  std::string toString() const override {
    return (llvm::Twine("dPrint(\"") + Id + "\")").str();
  }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    return printNode(Id, Match, Result);
  }
};

// Operators that take a single node Id as an argument.
enum class UnaryNodeOperator {
  Parens,
  Deref,
  MaybeDeref,
  AddressOf,
  MaybeAddressOf,
  Describe,
};

// Generic container for stencil operations with a (single) node-id argument.
class UnaryOperationStencil : public StencilInterface {
  UnaryNodeOperator Op;
  std::string Id;

public:
  UnaryOperationStencil(UnaryNodeOperator Op, std::string Id)
      : Op(Op), Id(std::move(Id)) {}

  std::string toString() const override {
    StringRef OpName;
    switch (Op) {
    case UnaryNodeOperator::Parens:
      OpName = "expression";
      break;
    case UnaryNodeOperator::Deref:
      OpName = "deref";
      break;
    case UnaryNodeOperator::MaybeDeref:
      OpName = "maybeDeref";
      break;
    case UnaryNodeOperator::AddressOf:
      OpName = "addressOf";
      break;
    case UnaryNodeOperator::MaybeAddressOf:
      OpName = "maybeAddressOf";
      break;
    case UnaryNodeOperator::Describe:
      OpName = "describe";
      break;
    }
    return (OpName + "(\"" + Id + "\")").str();
  }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    // The `Describe` operation can be applied to any node, not just
    // expressions, so it is handled here, separately.
    if (Op == UnaryNodeOperator::Describe)
      return printNode(Id, Match, Result);

    const auto *E = Match.Nodes.getNodeAs<Expr>(Id);
    if (E == nullptr)
      return llvm::make_error<StringError>(errc::invalid_argument,
                                           "Id not bound or not Expr: " + Id);
    std::optional<std::string> Source;
    switch (Op) {
    case UnaryNodeOperator::Parens:
      Source = tooling::buildParens(*E, *Match.Context);
      break;
    case UnaryNodeOperator::Deref:
      Source = tooling::buildDereference(*E, *Match.Context);
      break;
    case UnaryNodeOperator::MaybeDeref:
      if (E->getType()->isAnyPointerType() ||
          tooling::isKnownPointerLikeType(E->getType(), *Match.Context)) {
        // Strip off any operator->. This can only occur inside an actual arrow
        // member access, so we treat it as equivalent to an actual object
        // expression.
        if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(E)) {
          if (OpCall->getOperator() == clang::OO_Arrow &&
              OpCall->getNumArgs() == 1) {
            E = OpCall->getArg(0);
          }
        }
        Source = tooling::buildDereference(*E, *Match.Context);
        break;
      }
      *Result += tooling::getText(*E, *Match.Context);
      return Error::success();
    case UnaryNodeOperator::AddressOf:
      Source = tooling::buildAddressOf(*E, *Match.Context);
      break;
    case UnaryNodeOperator::MaybeAddressOf:
      if (E->getType()->isAnyPointerType() ||
          tooling::isKnownPointerLikeType(E->getType(), *Match.Context)) {
        // Strip off any operator->. This can only occur inside an actual arrow
        // member access, so we treat it as equivalent to an actual object
        // expression.
        if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(E)) {
          if (OpCall->getOperator() == clang::OO_Arrow &&
              OpCall->getNumArgs() == 1) {
            E = OpCall->getArg(0);
          }
        }
        *Result += tooling::getText(*E, *Match.Context);
        return Error::success();
      }
      Source = tooling::buildAddressOf(*E, *Match.Context);
      break;
    case UnaryNodeOperator::Describe:
      llvm_unreachable("This case is handled at the start of the function");
    }
    if (!Source)
      return llvm::make_error<StringError>(
          errc::invalid_argument,
          "Could not construct expression source from ID: " + Id);
    *Result += *Source;
    return Error::success();
  }
};

// The fragment of code corresponding to the selected range.
class SelectorStencil : public StencilInterface {
  RangeSelector Selector;

public:
  explicit SelectorStencil(RangeSelector S) : Selector(std::move(S)) {}

  std::string toString() const override { return "selection(...)"; }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    auto RawRange = Selector(Match);
    if (!RawRange)
      return RawRange.takeError();
    CharSourceRange Range = Lexer::makeFileCharRange(
        *RawRange, *Match.SourceManager, Match.Context->getLangOpts());
    if (Range.isInvalid()) {
      // Validate the original range to attempt to get a meaningful error
      // message. If it's valid, then something else is the cause and we just
      // return the generic failure message.
      if (auto Err = tooling::validateRange(*RawRange, *Match.SourceManager,
                                            /*AllowSystemHeaders=*/true))
        return handleErrors(std::move(Err), [](std::unique_ptr<StringError> E) {
          assert(E->convertToErrorCode() ==
                     llvm::make_error_code(errc::invalid_argument) &&
                 "Validation errors must carry the invalid_argument code");
          return llvm::createStringError(
              errc::invalid_argument,
              "selected range could not be resolved to a valid source range; " +
                  E->getMessage());
        });
      return llvm::createStringError(
          errc::invalid_argument,
          "selected range could not be resolved to a valid source range");
    }
    // Validate `Range`, because `makeFileCharRange` accepts some ranges that
    // `validateRange` rejects.
    if (auto Err = tooling::validateRange(Range, *Match.SourceManager,
                                          /*AllowSystemHeaders=*/true))
      return joinErrors(
          llvm::createStringError(errc::invalid_argument,
                                  "selected range is not valid for editing"),
          std::move(Err));
    *Result += tooling::getText(Range, *Match.Context);
    return Error::success();
  }
};

// A stencil operation to build a member access `e.m` or `e->m`, as appropriate.
class AccessStencil : public StencilInterface {
  std::string BaseId;
  Stencil Member;

public:
  AccessStencil(StringRef BaseId, Stencil Member)
      : BaseId(std::string(BaseId)), Member(std::move(Member)) {}

  std::string toString() const override {
    return (llvm::Twine("access(\"") + BaseId + "\", " + Member->toString() +
            ")")
        .str();
  }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    const auto *E = Match.Nodes.getNodeAs<Expr>(BaseId);
    if (E == nullptr)
      return llvm::make_error<StringError>(errc::invalid_argument,
                                           "Id not bound: " + BaseId);
    std::optional<std::string> S = tooling::buildAccess(*E, *Match.Context);
    if (!S)
      return llvm::make_error<StringError>(
          errc::invalid_argument,
          "Could not construct object text from ID: " + BaseId);
    *Result += *S;
    return Member->eval(Match, Result);
  }
};

class IfBoundStencil : public StencilInterface {
  std::string Id;
  Stencil TrueStencil;
  Stencil FalseStencil;

public:
  IfBoundStencil(StringRef Id, Stencil TrueStencil, Stencil FalseStencil)
      : Id(std::string(Id)), TrueStencil(std::move(TrueStencil)),
        FalseStencil(std::move(FalseStencil)) {}

  std::string toString() const override {
    return (llvm::Twine("ifBound(\"") + Id + "\", " + TrueStencil->toString() +
            ", " + FalseStencil->toString() + ")")
        .str();
  }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    auto &M = Match.Nodes.getMap();
    return (M.find(Id) != M.end() ? TrueStencil : FalseStencil)
        ->eval(Match, Result);
  }
};

class SelectBoundStencil : public clang::transformer::StencilInterface {
  static bool containsNoNullStencils(
      const std::vector<std::pair<std::string, Stencil>> &Cases) {
    for (const auto &S : Cases)
      if (S.second == nullptr)
        return false;
    return true;
  }

public:
  SelectBoundStencil(std::vector<std::pair<std::string, Stencil>> Cases,
                     Stencil Default)
      : CaseStencils(std::move(Cases)), DefaultStencil(std::move(Default)) {
    assert(containsNoNullStencils(CaseStencils) &&
           "cases of selectBound may not be null");
  }
  ~SelectBoundStencil() override {}

  llvm::Error eval(const MatchFinder::MatchResult &match,
                   std::string *result) const override {
    const BoundNodes::IDToNodeMap &NodeMap = match.Nodes.getMap();
    for (const auto &S : CaseStencils) {
      if (NodeMap.count(S.first) > 0) {
        return S.second->eval(match, result);
      }
    }

    if (DefaultStencil != nullptr) {
      return DefaultStencil->eval(match, result);
    }

    llvm::SmallVector<llvm::StringRef, 2> CaseIDs;
    CaseIDs.reserve(CaseStencils.size());
    for (const auto &S : CaseStencils)
      CaseIDs.emplace_back(S.first);

    return llvm::createStringError(
        errc::result_out_of_range,
        llvm::Twine("selectBound failed: no cases bound and no default: {") +
            llvm::join(CaseIDs, ", ") + "}");
  }

  std::string toString() const override {
    std::string Buffer;
    llvm::raw_string_ostream Stream(Buffer);
    Stream << "selectBound({";
    bool First = true;
    for (const auto &S : CaseStencils) {
      if (First)
        First = false;
      else
        Stream << "}, ";
      Stream << "{\"" << S.first << "\", " << S.second->toString();
    }
    Stream << "}}";
    if (DefaultStencil != nullptr) {
      Stream << ", " << DefaultStencil->toString();
    }
    Stream << ")";
    return Buffer;
  }

private:
  std::vector<std::pair<std::string, Stencil>> CaseStencils;
  Stencil DefaultStencil;
};

class SequenceStencil : public StencilInterface {
  std::vector<Stencil> Stencils;

public:
  SequenceStencil(std::vector<Stencil> Stencils)
      : Stencils(std::move(Stencils)) {}

  std::string toString() const override {
    llvm::SmallVector<std::string, 2> Parts;
    Parts.reserve(Stencils.size());
    for (const auto &S : Stencils)
      Parts.push_back(S->toString());
    return (llvm::Twine("seq(") + llvm::join(Parts, ", ") + ")").str();
  }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {
    for (const auto &S : Stencils)
      if (auto Err = S->eval(Match, Result))
        return Err;
    return Error::success();
  }
};

class RunStencil : public StencilInterface {
  MatchConsumer<std::string> Consumer;

public:
  explicit RunStencil(MatchConsumer<std::string> C) : Consumer(std::move(C)) {}

  std::string toString() const override { return "run(...)"; }

  Error eval(const MatchFinder::MatchResult &Match,
             std::string *Result) const override {

    Expected<std::string> Value = Consumer(Match);
    if (!Value)
      return Value.takeError();
    *Result += *Value;
    return Error::success();
  }
};
} // namespace

Stencil transformer::detail::makeStencil(StringRef Text) {
  return std::make_shared<RawTextStencil>(std::string(Text));
}

Stencil transformer::detail::makeStencil(RangeSelector Selector) {
  return std::make_shared<SelectorStencil>(std::move(Selector));
}

Stencil transformer::dPrint(StringRef Id) {
  return std::make_shared<DebugPrintNodeStencil>(std::string(Id));
}

Stencil transformer::expression(llvm::StringRef Id) {
  return std::make_shared<UnaryOperationStencil>(UnaryNodeOperator::Parens,
                                                 std::string(Id));
}

Stencil transformer::deref(llvm::StringRef ExprId) {
  return std::make_shared<UnaryOperationStencil>(UnaryNodeOperator::Deref,
                                                 std::string(ExprId));
}

Stencil transformer::maybeDeref(llvm::StringRef ExprId) {
  return std::make_shared<UnaryOperationStencil>(UnaryNodeOperator::MaybeDeref,
                                                 std::string(ExprId));
}

Stencil transformer::addressOf(llvm::StringRef ExprId) {
  return std::make_shared<UnaryOperationStencil>(UnaryNodeOperator::AddressOf,
                                                 std::string(ExprId));
}

Stencil transformer::maybeAddressOf(llvm::StringRef ExprId) {
  return std::make_shared<UnaryOperationStencil>(
      UnaryNodeOperator::MaybeAddressOf, std::string(ExprId));
}

Stencil transformer::describe(StringRef Id) {
  return std::make_shared<UnaryOperationStencil>(UnaryNodeOperator::Describe,
                                                 std::string(Id));
}

Stencil transformer::access(StringRef BaseId, Stencil Member) {
  return std::make_shared<AccessStencil>(BaseId, std::move(Member));
}

Stencil transformer::ifBound(StringRef Id, Stencil TrueStencil,
                             Stencil FalseStencil) {
  return std::make_shared<IfBoundStencil>(Id, std::move(TrueStencil),
                                          std::move(FalseStencil));
}

Stencil transformer::selectBound(
    std::vector<std::pair<std::string, Stencil>> CaseStencils,
    Stencil DefaultStencil) {
  return std::make_shared<SelectBoundStencil>(std::move(CaseStencils),
                                              std::move(DefaultStencil));
}

Stencil transformer::run(MatchConsumer<std::string> Fn) {
  return std::make_shared<RunStencil>(std::move(Fn));
}

Stencil transformer::catVector(std::vector<Stencil> Parts) {
  // Only one argument, so don't wrap in sequence.
  if (Parts.size() == 1)
    return std::move(Parts[0]);
  return std::make_shared<SequenceStencil>(std::move(Parts));
}
