#include "../CtxInstrProfiling.h"
#include "gtest/gtest.h"
#include <thread>

using namespace __ctx_profile;

class ContextTest : public ::testing::Test {
  void SetUp() override { memset(&Root, 0, sizeof(ContextRoot)); }
  void TearDown() override { __llvm_ctx_profile_free(); }

public:
  ContextRoot Root;
};

TEST(ArenaTest, ZeroInit) {
  char Buffer[1024];
  memset(Buffer, 1, 1024);
  Arena *A = new (Buffer) Arena(10);
  for (auto I = 0U; I < A->size(); ++I)
    EXPECT_EQ(A->pos()[I], static_cast<char>(0));
  EXPECT_EQ(A->size(), 10U);
}

TEST(ArenaTest, Basic) {
  Arena *A = Arena::allocateNewArena(1024);
  EXPECT_EQ(A->size(), 1024U);
  EXPECT_EQ(A->next(), nullptr);

  auto *M1 = A->tryBumpAllocate(1020);
  EXPECT_NE(M1, nullptr);
  auto *M2 = A->tryBumpAllocate(4);
  EXPECT_NE(M2, nullptr);
  EXPECT_EQ(M1 + 1020, M2);
  EXPECT_EQ(A->tryBumpAllocate(1), nullptr);
  Arena *A2 = Arena::allocateNewArena(2024, A);
  EXPECT_EQ(A->next(), A2);
  EXPECT_EQ(A2->next(), nullptr);
  Arena::freeArenaList(A);
  EXPECT_EQ(A, nullptr);
}

TEST_F(ContextTest, Basic) {
  __llvm_ctx_profile_start_collection();
  auto *Ctx = __llvm_ctx_profile_start_context(&Root, 1, 10, 4);
  ASSERT_NE(Ctx, nullptr);
  EXPECT_NE(Root.CurrentMem, nullptr);
  EXPECT_EQ(Root.FirstMemBlock, Root.CurrentMem);
  EXPECT_EQ(Ctx->size(), sizeof(ContextNode) + 10 * sizeof(uint64_t) +
                             4 * sizeof(ContextNode *));
  EXPECT_EQ(Ctx->counters_size(), 10U);
  EXPECT_EQ(Ctx->callsites_size(), 4U);
  EXPECT_EQ(__llvm_ctx_profile_current_context_root, &Root);
  Root.Taken.CheckLocked();
  EXPECT_FALSE(Root.Taken.TryLock());
  __llvm_ctx_profile_release_context(&Root);
  EXPECT_EQ(__llvm_ctx_profile_current_context_root, nullptr);
  EXPECT_TRUE(Root.Taken.TryLock());
  Root.Taken.Unlock();
}

TEST_F(ContextTest, Callsite) {
  __llvm_ctx_profile_start_collection();
  auto *Ctx = __llvm_ctx_profile_start_context(&Root, 1, 10, 4);
  int FakeCalleeAddress = 0;
  const bool IsScratch = isScratch(Ctx);
  EXPECT_FALSE(IsScratch);
  // This is the sequence the caller performs - it's the lowering of the
  // instrumentation of the callsite "2". "2" is arbitrary here.
  __llvm_ctx_profile_expected_callee[0] = &FakeCalleeAddress;
  __llvm_ctx_profile_callsite[0] = &Ctx->subContexts()[2];
  // This is what the callee does
  FunctionData FData;
  auto *Subctx =
      __llvm_ctx_profile_get_context(&FData, &FakeCalleeAddress, 2, 3, 1);
  // This should not have required creating a flat context.
  EXPECT_EQ(FData.FlatCtx, nullptr);
  // We expect the subcontext to be appropriately placed and dimensioned
  EXPECT_EQ(Ctx->subContexts()[2], Subctx);
  EXPECT_EQ(Subctx->counters_size(), 3U);
  EXPECT_EQ(Subctx->callsites_size(), 1U);
  // We reset these in _get_context.
  EXPECT_EQ(__llvm_ctx_profile_expected_callee[0], nullptr);
  EXPECT_EQ(__llvm_ctx_profile_callsite[0], nullptr);

  EXPECT_EQ(Subctx->size(), sizeof(ContextNode) + 3 * sizeof(uint64_t) +
                                1 * sizeof(ContextNode *));
  __llvm_ctx_profile_release_context(&Root);
}

TEST_F(ContextTest, ScratchNoCollectionProfilingNotStarted) {
  // This test intentionally does not call __llvm_ctx_profile_start_collection.
  EXPECT_EQ(__llvm_ctx_profile_current_context_root, nullptr);
  int FakeCalleeAddress = 0;
  // this would be the very first function executing this. the TLS is empty,
  // too.
  FunctionData FData;
  auto *Ctx =
      __llvm_ctx_profile_get_context(&FData, &FakeCalleeAddress, 2, 3, 1);
  // We never entered a context (_start_context was never called) - so the
  // returned context must be a tagged pointer.
  EXPECT_TRUE(isScratch(Ctx));
  // Because we didn't start collection, no flat profile should have been
  // allocated.
  EXPECT_EQ(FData.FlatCtx, nullptr);
}

TEST_F(ContextTest, ScratchNoCollectionProfilingStarted) {
  ASSERT_EQ(__llvm_ctx_profile_current_context_root, nullptr);
  int FakeCalleeAddress = 0;
  // Start collection, so the function gets a flat profile instead of scratch.
  __llvm_ctx_profile_start_collection();
  // this would be the very first function executing this. the TLS is empty,
  // too.
  FunctionData FData;
  auto *Ctx =
      __llvm_ctx_profile_get_context(&FData, &FakeCalleeAddress, 2, 3, 1);
  // We never entered a context (_start_context was never called) - so the
  // returned context must be a tagged pointer.
  EXPECT_TRUE(isScratch(Ctx));
  // Because we never entered a context, we should have allocated a flat context
  EXPECT_NE(FData.FlatCtx, nullptr);
  EXPECT_EQ(reinterpret_cast<uintptr_t>(FData.FlatCtx) + 1,
            reinterpret_cast<uintptr_t>(Ctx));
}

TEST_F(ContextTest, ScratchDuringCollection) {
  __llvm_ctx_profile_start_collection();
  auto *Ctx = __llvm_ctx_profile_start_context(&Root, 1, 10, 4);
  int FakeCalleeAddress = 0;
  int OtherFakeCalleeAddress = 0;
  __llvm_ctx_profile_expected_callee[0] = &FakeCalleeAddress;
  __llvm_ctx_profile_callsite[0] = &Ctx->subContexts()[2];
  FunctionData FData[3];
  auto *Subctx = __llvm_ctx_profile_get_context(
      &FData[0], &OtherFakeCalleeAddress, 2, 3, 1);
  // We expected a different callee - so return scratch. It mimics what happens
  // in the case of a signal handler - in this case, OtherFakeCalleeAddress is
  // the signal handler.
  EXPECT_TRUE(isScratch(Subctx));
  // We shouldn't have tried to return a flat context because we're under a
  // root.
  EXPECT_EQ(FData[0].FlatCtx, nullptr);
  EXPECT_EQ(__llvm_ctx_profile_expected_callee[0], nullptr);
  EXPECT_EQ(__llvm_ctx_profile_callsite[0], nullptr);

  int ThirdFakeCalleeAddress = 0;
  __llvm_ctx_profile_expected_callee[1] = &ThirdFakeCalleeAddress;
  __llvm_ctx_profile_callsite[1] = &Subctx->subContexts()[0];

  auto *Subctx2 = __llvm_ctx_profile_get_context(
      &FData[1], &ThirdFakeCalleeAddress, 3, 0, 0);
  // We again expect scratch because the '0' position is where the runtime
  // looks, so it doesn't matter the '1' position is populated correctly.
  EXPECT_TRUE(isScratch(Subctx2));
  EXPECT_EQ(FData[1].FlatCtx, nullptr);

  __llvm_ctx_profile_expected_callee[0] = &ThirdFakeCalleeAddress;
  __llvm_ctx_profile_callsite[0] = &Subctx->subContexts()[0];
  auto *Subctx3 = __llvm_ctx_profile_get_context(
      &FData[2], &ThirdFakeCalleeAddress, 3, 0, 0);
  // We expect scratch here, too, because the value placed in
  // __llvm_ctx_profile_callsite is scratch
  EXPECT_TRUE(isScratch(Subctx3));
  EXPECT_EQ(FData[2].FlatCtx, nullptr);

  __llvm_ctx_profile_release_context(&Root);
}

TEST_F(ContextTest, NeedMoreMemory) {
  __llvm_ctx_profile_start_collection();
  auto *Ctx = __llvm_ctx_profile_start_context(&Root, 1, 10, 4);
  int FakeCalleeAddress = 0;
  const bool IsScratch = isScratch(Ctx);
  EXPECT_FALSE(IsScratch);
  const auto *CurrentMem = Root.CurrentMem;
  __llvm_ctx_profile_expected_callee[0] = &FakeCalleeAddress;
  __llvm_ctx_profile_callsite[0] = &Ctx->subContexts()[2];
  FunctionData FData;
  // Allocate a massive subcontext to force new arena allocation
  auto *Subctx =
      __llvm_ctx_profile_get_context(&FData, &FakeCalleeAddress, 3, 1 << 20, 1);
  EXPECT_EQ(FData.FlatCtx, nullptr);
  EXPECT_EQ(Ctx->subContexts()[2], Subctx);
  EXPECT_NE(CurrentMem, Root.CurrentMem);
  EXPECT_NE(Root.CurrentMem, nullptr);
}

TEST_F(ContextTest, ConcurrentRootCollection) {
  std::atomic<int> NonScratch = 0;
  std::atomic<int> Executions = 0;

  __sanitizer::Semaphore GotCtx;

  auto Entrypoint = [&]() {
    ++Executions;
    auto *Ctx = __llvm_ctx_profile_start_context(&Root, 1, 10, 4);
    GotCtx.Post();
    const bool IS = isScratch(Ctx);
    NonScratch += (!IS);
    if (!IS) {
      GotCtx.Wait();
      GotCtx.Wait();
    }
    __llvm_ctx_profile_release_context(&Root);
  };
  std::thread T1(Entrypoint);
  std::thread T2(Entrypoint);
  T1.join();
  T2.join();
  EXPECT_EQ(NonScratch, 1);
  EXPECT_EQ(Executions, 2);
}

TEST_F(ContextTest, Dump) {
  auto *Ctx = __llvm_ctx_profile_start_context(&Root, 1, 10, 4);
  int FakeCalleeAddress = 0;
  __llvm_ctx_profile_expected_callee[0] = &FakeCalleeAddress;
  __llvm_ctx_profile_callsite[0] = &Ctx->subContexts()[2];
  FunctionData FData;
  auto *Subctx =
      __llvm_ctx_profile_get_context(&FData, &FakeCalleeAddress, 2, 3, 1);
  (void)Subctx;
  __llvm_ctx_profile_release_context(&Root);

  class TestProfileWriter : public ProfileWriter {
  public:
    ContextRoot *const Root;
    const size_t Entries;

    int EnteredSectionCount = 0;
    int ExitedSectionCount = 0;
    int EnteredFlatCount = 0;
    int ExitedFlatCount = 0;
    int FlatsWritten = 0;

    bool State = false;

    TestProfileWriter(ContextRoot *Root, size_t Entries)
        : Root(Root), Entries(Entries) {}

    void writeContextual(const ContextNode &Node) override {
      EXPECT_EQ(EnteredSectionCount, 1);
      EXPECT_EQ(ExitedSectionCount, 0);
      EXPECT_FALSE(Root->Taken.TryLock());
      EXPECT_EQ(Node.guid(), 1U);
      EXPECT_EQ(Node.counters()[0], Entries);
      EXPECT_EQ(Node.counters_size(), 10U);
      EXPECT_EQ(Node.callsites_size(), 4U);
      EXPECT_EQ(Node.subContexts()[0], nullptr);
      EXPECT_EQ(Node.subContexts()[1], nullptr);
      EXPECT_NE(Node.subContexts()[2], nullptr);
      EXPECT_EQ(Node.subContexts()[3], nullptr);
      const auto &SN = *Node.subContexts()[2];
      EXPECT_EQ(SN.guid(), 2U);
      EXPECT_EQ(SN.counters()[0], Entries);
      EXPECT_EQ(SN.counters_size(), 3U);
      EXPECT_EQ(SN.callsites_size(), 1U);
      EXPECT_EQ(SN.subContexts()[0], nullptr);
      State = true;
    }
    void startContextSection() override { ++EnteredSectionCount; }
    void endContextSection() override {
      EXPECT_EQ(EnteredSectionCount, 1);
      ++ExitedSectionCount;
    }
    void startFlatSection() override { ++EnteredFlatCount; }
    void writeFlat(GUID Guid, const uint64_t *Buffer,
                   size_t BufferSize) override {
      ++FlatsWritten;
      EXPECT_EQ(BufferSize, 3U);
      EXPECT_EQ(Buffer[0], 15U);
      EXPECT_EQ(Buffer[1], 0U);
      EXPECT_EQ(Buffer[2], 0U);
    }
    void endFlatSection() override { ++ExitedFlatCount; }
  };

  TestProfileWriter W(&Root, 1);
  EXPECT_FALSE(W.State);
  __llvm_ctx_profile_fetch(W);
  EXPECT_TRUE(W.State);

  // this resets all counters but not the internal structure.
  __llvm_ctx_profile_start_collection();
  auto *Flat =
      __llvm_ctx_profile_get_context(&FData, &FakeCalleeAddress, 2, 3, 1);
  (void)Flat;
  EXPECT_NE(FData.FlatCtx, nullptr);
  FData.FlatCtx->counters()[0] = 15U;
  TestProfileWriter W2(&Root, 0);
  EXPECT_FALSE(W2.State);
  __llvm_ctx_profile_fetch(W2);
  EXPECT_TRUE(W2.State);
  EXPECT_EQ(W2.EnteredSectionCount, 1);
  EXPECT_EQ(W2.ExitedSectionCount, 1);
  EXPECT_EQ(W2.EnteredFlatCount, 1);
  EXPECT_EQ(W2.FlatsWritten, 1);
  EXPECT_EQ(W2.ExitedFlatCount, 1);
}
