//===-- TraceTests.cpp - Tracing unit tests ---------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Trace.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/YAMLParser.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace clang {
namespace clangd {
namespace {
using namespace llvm;

MATCHER_P(StringNode, Val, "") {
  if (arg->getType() != yaml::Node::NK_Scalar) {
    *result_listener << "is a " << arg->getVerbatimTag();
    return false;
  }
  SmallString<32> S;
  return Val == static_cast<yaml::ScalarNode *>(arg)->getValue(S);
}

// Checks that N is a Mapping (JS object) with the expected scalar properties.
// The object must have all the Expected properties, but may have others.
bool VerifyObject(yaml::Node &N, std::map<std::string, std::string> Expected) {
  auto *M = dyn_cast<yaml::MappingNode>(&N);
  if (!M) {
    ADD_FAILURE() << "Not an object";
    return false;
  }
  bool Match = true;
  SmallString<32> Tmp;
  for (auto &Prop : *M) {
    auto *K = dyn_cast_or_null<yaml::ScalarNode>(Prop.getKey());
    if (!K)
      continue;
    std::string KS = K->getValue(Tmp).str();
    auto I = Expected.find(KS);
    if (I == Expected.end())
      continue; // Ignore properties with no assertion.

    auto *V = dyn_cast_or_null<yaml::ScalarNode>(Prop.getValue());
    if (!V) {
      ADD_FAILURE() << KS << " is not a string";
      Match = false;
    }
    std::string VS = V->getValue(Tmp).str();
    if (VS != I->second) {
      ADD_FAILURE() << KS << " expected " << I->second << " but actual " << VS;
      Match = false;
    }
    Expected.erase(I);
  }
  for (const auto &P : Expected) {
    ADD_FAILURE() << P.first << " missing, expected " << P.second;
    Match = false;
  }
  return Match;
}

TEST(TraceTest, SmokeTest) {
  // Capture some events.
  std::string JSON;
  {
    raw_string_ostream OS(JSON);
    auto JSONTracer = trace::createJSONTracer(OS);
    trace::Session Session(*JSONTracer);
    {
      trace::Span Tracer("A");
      trace::log("B");
    }
  }

  // Get the root JSON object using the YAML parser.
  SourceMgr SM;
  yaml::Stream Stream(JSON, SM);
  auto Doc = Stream.begin();
  ASSERT_NE(Doc, Stream.end());
  auto *Root = dyn_cast_or_null<yaml::MappingNode>(Doc->getRoot());
  ASSERT_NE(Root, nullptr) << "Root should be an object";

  // Check whether we expect thread name events on this platform.
  SmallString<32> ThreadName;
  llvm::get_thread_name(ThreadName);
  bool ThreadsHaveNames = !ThreadName.empty();

  // We expect in order:
  //   displayTimeUnit: "ns"
  //   traceEvents: [process name, thread name, start span, log, end span]
  // (The order doesn't matter, but the YAML parser is awkward to use otherwise)
  auto Prop = Root->begin();
  ASSERT_NE(Prop, Root->end()) << "Expected displayTimeUnit property";
  ASSERT_THAT(Prop->getKey(), StringNode("displayTimeUnit"));
  EXPECT_THAT(Prop->getValue(), StringNode("ns"));
  ASSERT_NE(++Prop, Root->end()) << "Expected traceEvents property";
  EXPECT_THAT(Prop->getKey(), StringNode("traceEvents"));
  auto *Events = dyn_cast_or_null<yaml::SequenceNode>(Prop->getValue());
  ASSERT_NE(Events, nullptr) << "traceEvents should be an array";
  auto Event = Events->begin();
  ASSERT_NE(Event, Events->end()) << "Expected process name";
  EXPECT_TRUE(VerifyObject(*Event, {{"ph", "M"}, {"name", "process_name"}}));
  if (ThreadsHaveNames) {
    ASSERT_NE(++Event, Events->end()) << "Expected thread name";
    EXPECT_TRUE(VerifyObject(*Event, {{"ph", "M"}, {"name", "thread_name"}}));
  }
  ASSERT_NE(++Event, Events->end()) << "Expected log message";
  EXPECT_TRUE(VerifyObject(*Event, {{"ph", "i"}, {"name", "Log"}}));
  ASSERT_NE(++Event, Events->end()) << "Expected span end";
  EXPECT_TRUE(VerifyObject(*Event, {{"ph", "X"}, {"name", "A"}}));
  ASSERT_EQ(++Event, Events->end());
  ASSERT_EQ(++Prop, Root->end());
}

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