//===--- 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/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/Transformer/SourceCode.h"
#include "clang/Tooling/Transformer/SourceCodeBuilders.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Errc.h"
#include <atomic>
#include <memory>
#include <string>

using namespace clang;
using namespace tooling;

using ast_matchers::MatchFinder;
using ast_type_traits::DynTypedNode;
using llvm::errc;
using llvm::Error;
using llvm::Expected;
using llvm::StringError;

// A down_cast function to safely down cast a StencilPartInterface to a subclass
// D. Returns nullptr if P is not an instance of D.
template <typename D> const D *down_cast(const StencilPartInterface *P) {
  if (P == nullptr || D::typeId() != P->typeId())
    return nullptr;
  return static_cast<const D *>(P);
}

static llvm::Expected<DynTypedNode>
getNode(const ast_matchers::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;
}

namespace {
// An arbitrary fragment of code within a stencil.
struct RawTextData {
  explicit RawTextData(std::string T) : Text(std::move(T)) {}
  std::string Text;
};

// A debugging operation to dump the AST for a particular (bound) AST node.
struct DebugPrintNodeData {
  explicit DebugPrintNodeData(std::string S) : Id(std::move(S)) {}
  std::string Id;
};

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

// Generic container for stencil operations with a (single) node-id argument.
struct UnaryOperationData {
  UnaryOperationData(UnaryNodeOperator Op, std::string Id)
      : Op(Op), Id(std::move(Id)) {}
  UnaryNodeOperator Op;
  std::string Id;
};

// The fragment of code corresponding to the selected range.
struct SelectorData {
  explicit SelectorData(RangeSelector S) : Selector(std::move(S)) {}
  RangeSelector Selector;
};

// A stencil operation to build a member access `e.m` or `e->m`, as appropriate.
struct AccessData {
  AccessData(StringRef BaseId, StencilPart Member)
      : BaseId(BaseId), Member(std::move(Member)) {}
  std::string BaseId;
  StencilPart Member;
};

struct IfBoundData {
  IfBoundData(StringRef Id, StencilPart TruePart, StencilPart FalsePart)
      : Id(Id), TruePart(std::move(TruePart)), FalsePart(std::move(FalsePart)) {
  }
  std::string Id;
  StencilPart TruePart;
  StencilPart FalsePart;
};

bool isEqualData(const RawTextData &A, const RawTextData &B) {
  return A.Text == B.Text;
}

bool isEqualData(const DebugPrintNodeData &A, const DebugPrintNodeData &B) {
  return A.Id == B.Id;
}

bool isEqualData(const UnaryOperationData &A, const UnaryOperationData &B) {
  return A.Op == B.Op && A.Id == B.Id;
}

// Equality is not (yet) defined for \c RangeSelector.
bool isEqualData(const SelectorData &, const SelectorData &) { return false; }

bool isEqualData(const AccessData &A, const AccessData &B) {
  return A.BaseId == B.BaseId && A.Member == B.Member;
}

bool isEqualData(const IfBoundData &A, const IfBoundData &B) {
  return A.Id == B.Id && A.TruePart == B.TruePart && A.FalsePart == B.FalsePart;
}

// Equality is not defined over MatchConsumers, which are opaque.
bool isEqualData(const MatchConsumer<std::string> &A,
                 const MatchConsumer<std::string> &B) {
  return false;
}

std::string toStringData(const RawTextData &Data) {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  OS << "\"";
  OS.write_escaped(Data.Text);
  OS << "\"";
  OS.flush();
  return Result;
}

std::string toStringData(const DebugPrintNodeData &Data) {
  return (llvm::Twine("dPrint(\"") + Data.Id + "\")").str();
}

std::string toStringData(const UnaryOperationData &Data) {
  StringRef OpName;
  switch (Data.Op) {
  case UnaryNodeOperator::Parens:
    OpName = "expression";
    break;
  case UnaryNodeOperator::Deref:
    OpName = "deref";
    break;
  case UnaryNodeOperator::Address:
    OpName = "addressOf";
    break;
  }
  return (OpName + "(\"" + Data.Id + "\")").str();
}

std::string toStringData(const SelectorData &) { return "SelectorData()"; }

std::string toStringData(const AccessData &Data) {
  return (llvm::Twine("access(\"") + Data.BaseId + "\", " +
          Data.Member.toString() + ")")
      .str();
}

std::string toStringData(const IfBoundData &Data) {
  return (llvm::Twine("ifBound(\"") + Data.Id + "\", " +
          Data.TruePart.toString() + ", " + Data.FalsePart.toString() + ")")
      .str();
}

std::string toStringData(const MatchConsumer<std::string> &) {
  return "MatchConsumer<std::string>()";
}

// The `evalData()` overloads evaluate the given stencil data to a string, given
// the match result, and append it to `Result`. We define an overload for each
// type of stencil data.

Error evalData(const RawTextData &Data, const MatchFinder::MatchResult &,
               std::string *Result) {
  Result->append(Data.Text);
  return Error::success();
}

Error evalData(const DebugPrintNodeData &Data,
               const MatchFinder::MatchResult &Match, std::string *Result) {
  std::string Output;
  llvm::raw_string_ostream Os(Output);
  auto NodeOrErr = getNode(Match.Nodes, Data.Id);
  if (auto Err = NodeOrErr.takeError())
    return Err;
  NodeOrErr->print(Os, PrintingPolicy(Match.Context->getLangOpts()));
  *Result += Os.str();
  return Error::success();
}

Error evalData(const UnaryOperationData &Data,
               const MatchFinder::MatchResult &Match, std::string *Result) {
  const auto *E = Match.Nodes.getNodeAs<Expr>(Data.Id);
  if (E == nullptr)
    return llvm::make_error<StringError>(
        errc::invalid_argument, "Id not bound or not Expr: " + Data.Id);
  llvm::Optional<std::string> Source;
  switch (Data.Op) {
  case UnaryNodeOperator::Parens:
    Source = buildParens(*E, *Match.Context);
    break;
  case UnaryNodeOperator::Deref:
    Source = buildDereference(*E, *Match.Context);
    break;
  case UnaryNodeOperator::Address:
    Source = buildAddressOf(*E, *Match.Context);
    break;
  }
  if (!Source)
    return llvm::make_error<StringError>(
        errc::invalid_argument,
        "Could not construct expression source from ID: " + Data.Id);
  *Result += *Source;
  return Error::success();
}

Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match,
               std::string *Result) {
  auto Range = Data.Selector(Match);
  if (!Range)
    return Range.takeError();
  *Result += getText(*Range, *Match.Context);
  return Error::success();
}

Error evalData(const AccessData &Data, const MatchFinder::MatchResult &Match,
               std::string *Result) {
  const auto *E = Match.Nodes.getNodeAs<Expr>(Data.BaseId);
  if (E == nullptr)
    return llvm::make_error<StringError>(errc::invalid_argument,
                                         "Id not bound: " + Data.BaseId);
  if (!E->isImplicitCXXThis()) {
    if (llvm::Optional<std::string> S = E->getType()->isAnyPointerType()
                                            ? buildArrow(*E, *Match.Context)
                                            : buildDot(*E, *Match.Context))
      *Result += *S;
    else
      return llvm::make_error<StringError>(
          errc::invalid_argument,
          "Could not construct object text from ID: " + Data.BaseId);
  }
  return Data.Member.eval(Match, Result);
}

Error evalData(const IfBoundData &Data, const MatchFinder::MatchResult &Match,
               std::string *Result) {
  auto &M = Match.Nodes.getMap();
  return (M.find(Data.Id) != M.end() ? Data.TruePart : Data.FalsePart)
      .eval(Match, Result);
}

Error evalData(const MatchConsumer<std::string> &Fn,
               const MatchFinder::MatchResult &Match, std::string *Result) {
  Expected<std::string> Value = Fn(Match);
  if (!Value)
    return Value.takeError();
  *Result += *Value;
  return Error::success();
}

template <typename T>
class StencilPartImpl : public StencilPartInterface {
  T Data;

public:
  template <typename... Ps>
  explicit StencilPartImpl(Ps &&... Args)
      : StencilPartInterface(StencilPartImpl::typeId()),
        Data(std::forward<Ps>(Args)...) {}

  // Generates a unique identifier for this class (specifically, one per
  // instantiation of the template).
  static const void* typeId() {
    static bool b;
    return &b;
  }

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

  bool isEqual(const StencilPartInterface &Other) const override {
    if (const auto *OtherPtr = down_cast<StencilPartImpl>(&Other))
      return isEqualData(Data, OtherPtr->Data);
    return false;
  }

  std::string toString() const override { return toStringData(Data); }
};
} // namespace

StencilPart Stencil::wrap(StringRef Text) {
  return stencil::text(Text);
}

StencilPart Stencil::wrap(RangeSelector Selector) {
  return stencil::selection(std::move(Selector));
}

void Stencil::append(Stencil OtherStencil) {
  for (auto &Part : OtherStencil.Parts)
    Parts.push_back(std::move(Part));
}

llvm::Expected<std::string>
Stencil::eval(const MatchFinder::MatchResult &Match) const {
  std::string Result;
  for (const auto &Part : Parts)
    if (auto Err = Part.eval(Match, &Result))
      return std::move(Err);
  return Result;
}

StencilPart stencil::text(StringRef Text) {
  return StencilPart(std::make_shared<StencilPartImpl<RawTextData>>(Text));
}

StencilPart stencil::selection(RangeSelector Selector) {
  return StencilPart(
      std::make_shared<StencilPartImpl<SelectorData>>(std::move(Selector)));
}

StencilPart stencil::dPrint(StringRef Id) {
  return StencilPart(std::make_shared<StencilPartImpl<DebugPrintNodeData>>(Id));
}

StencilPart stencil::expression(llvm::StringRef Id) {
  return StencilPart(std::make_shared<StencilPartImpl<UnaryOperationData>>(
      UnaryNodeOperator::Parens, Id));
}

StencilPart stencil::deref(llvm::StringRef ExprId) {
  return StencilPart(std::make_shared<StencilPartImpl<UnaryOperationData>>(
      UnaryNodeOperator::Deref, ExprId));
}

StencilPart stencil::addressOf(llvm::StringRef ExprId) {
  return StencilPart(std::make_shared<StencilPartImpl<UnaryOperationData>>(
      UnaryNodeOperator::Address, ExprId));
}

StencilPart stencil::access(StringRef BaseId, StencilPart Member) {
  return StencilPart(
      std::make_shared<StencilPartImpl<AccessData>>(BaseId, std::move(Member)));
}

StencilPart stencil::ifBound(StringRef Id, StencilPart TruePart,
                             StencilPart FalsePart) {
  return StencilPart(std::make_shared<StencilPartImpl<IfBoundData>>(
      Id, std::move(TruePart), std::move(FalsePart)));
}

StencilPart stencil::run(MatchConsumer<std::string> Fn) {
  return StencilPart(
      std::make_shared<StencilPartImpl<MatchConsumer<std::string>>>(
          std::move(Fn)));
}
