#include "TestingSupport.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"

namespace clang::dataflow::test {
namespace {
using testing::HasSubstr;

struct TestLattice {
  int Elements = 0;
  int Branches = 0;
  int Joins = 0;

  LatticeJoinEffect join(const TestLattice &Other) {
    if (Joins < 3) {
      ++Joins;
      Elements += Other.Elements;
      Branches += Other.Branches;
      return LatticeJoinEffect::Changed;
    }
    return LatticeJoinEffect::Unchanged;
  }
  friend bool operator==(const TestLattice &LHS, const TestLattice &RHS) {
    return std::tie(LHS.Elements, LHS.Branches, LHS.Joins) ==
           std::tie(RHS.Elements, RHS.Branches, RHS.Joins);
  }
};

class TestAnalysis : public DataflowAnalysis<TestAnalysis, TestLattice> {
public:
  using DataflowAnalysis::DataflowAnalysis;

  static TestLattice initialElement() { return TestLattice{}; }
  void transfer(const CFGElement &, TestLattice &L, Environment &E) {
    E.getDataflowAnalysisContext().getOptions().Log->log(
        [](llvm::raw_ostream &OS) { OS << "transfer()"; });
    ++L.Elements;
  }
  void transferBranch(bool Branch, const Stmt *S, TestLattice &L,
                      Environment &E) {
    E.getDataflowAnalysisContext().getOptions().Log->log(
        [&](llvm::raw_ostream &OS) {
          OS << "transferBranch(" << Branch << ")";
        });
    ++L.Branches;
  }
};

class TestLogger : public Logger {
public:
  TestLogger(std::string &S) : OS(S) {}

private:
  llvm::raw_string_ostream OS;

  void beginAnalysis(const AdornedCFG &,
                     TypeErasedDataflowAnalysis &) override {
    logText("beginAnalysis()");
  }
  void endAnalysis() override { logText("\nendAnalysis()"); }

  void enterBlock(const CFGBlock &B, bool PostVisit) override {
    OS << "\nenterBlock(" << B.BlockID << ", " << (PostVisit ? "true" : "false")
       << ")\n";
  }
  void enterElement(const CFGElement &E) override {
    // we don't want the trailing \n
    std::string S;
    llvm::raw_string_ostream SS(S);
    E.dumpToStream(SS);

    OS << "enterElement(" << llvm::StringRef(S).trim() << ")\n";
  }
  void recordState(TypeErasedDataflowAnalysisState &S) override {
    const TestLattice &L = llvm::any_cast<TestLattice>(S.Lattice.Value);
    OS << "recordState(Elements=" << L.Elements << ", Branches=" << L.Branches
       << ", Joins=" << L.Joins << ")\n";
  }
  /// Records that the analysis state for the current block is now final.
  void blockConverged() override { logText("blockConverged()"); }

  void logText(llvm::StringRef Text) override { OS << Text << "\n"; }
};

AnalysisInputs<TestAnalysis> makeInputs() {
  const char *Code = R"cpp(
int target(bool b, int p, int q) {
  return b ? p : q;
}
)cpp";
  static const std::vector<std::string> Args = {
      "-fsyntax-only", "-fno-delayed-template-parsing", "-std=c++17"};

  auto Inputs = AnalysisInputs<TestAnalysis>(
      Code, ast_matchers::hasName("target"),
      [](ASTContext &C, Environment &) { return TestAnalysis(C); });
  Inputs.ASTBuildArgs = Args;
  return Inputs;
}

TEST(LoggerTest, Sequence) {
  auto Inputs = makeInputs();
  std::string Log;
  TestLogger Logger(Log);
  Inputs.BuiltinOptions.Log = &Logger;

  ASSERT_THAT_ERROR(checkDataflow<TestAnalysis>(std::move(Inputs),
                                                [](const AnalysisOutputs &) {}),
                    llvm::Succeeded());

  EXPECT_EQ(Log, R"(beginAnalysis()

enterBlock(4, false)
recordState(Elements=0, Branches=0, Joins=0)
enterElement(b)
transfer()
recordState(Elements=1, Branches=0, Joins=0)
enterElement(b (ImplicitCastExpr, LValueToRValue, _Bool))
transfer()
recordState(Elements=2, Branches=0, Joins=0)
recordState(Elements=2, Branches=0, Joins=0)

enterBlock(2, false)
transferBranch(1)
recordState(Elements=2, Branches=1, Joins=0)
enterElement(p)
transfer()
recordState(Elements=3, Branches=1, Joins=0)

enterBlock(3, false)
transferBranch(0)
recordState(Elements=2, Branches=1, Joins=0)
enterElement(q)
transfer()
recordState(Elements=3, Branches=1, Joins=0)

enterBlock(1, false)
recordState(Elements=6, Branches=2, Joins=1)
enterElement(b ? p : q)
transfer()
recordState(Elements=7, Branches=2, Joins=1)
enterElement(b ? p : q (ImplicitCastExpr, LValueToRValue, int))
transfer()
recordState(Elements=8, Branches=2, Joins=1)
enterElement(return b ? p : q;)
transfer()
recordState(Elements=9, Branches=2, Joins=1)

enterBlock(0, false)
recordState(Elements=9, Branches=2, Joins=1)

endAnalysis()
)");
}

TEST(LoggerTest, HTML) {
  auto Inputs = makeInputs();
  std::vector<std::string> Logs;
  auto Logger = Logger::html([&]() {
    Logs.emplace_back();
    return std::make_unique<llvm::raw_string_ostream>(Logs.back());
  });
  Inputs.BuiltinOptions.Log = Logger.get();

  ASSERT_THAT_ERROR(checkDataflow<TestAnalysis>(std::move(Inputs),
                                                [](const AnalysisOutputs &) {}),
                    llvm::Succeeded());

  // Simple smoke tests: we can't meaningfully test the behavior.
  ASSERT_THAT(Logs, testing::SizeIs(1));
  EXPECT_THAT(Logs[0], HasSubstr("function updateSelection")) << "embeds JS";
  EXPECT_THAT(Logs[0], HasSubstr("html {")) << "embeds CSS";
  EXPECT_THAT(Logs[0], HasSubstr("b (ImplicitCastExpr")) << "has CFG elements";
  EXPECT_THAT(Logs[0], HasSubstr("\"B3:1_B3.1\":"))
      << "has analysis point state";
  EXPECT_THAT(Logs[0], HasSubstr("transferBranch(0)")) << "has analysis logs";
  EXPECT_THAT(Logs[0], HasSubstr("LocToVal")) << "has built-in lattice dump";
  EXPECT_THAT(Logs[0], HasSubstr("\"type\": \"int\"")) << "has value dump";
}

} // namespace
} // namespace clang::dataflow::test
