//===--- Trace.cpp - Performance tracing facilities -----------------------===//
//
// 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 "support/Trace.h"
#include "support/Context.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Threading.h"
#include <atomic>
#include <chrono>
#include <memory>
#include <mutex>

namespace clang {
namespace clangd {
namespace trace {

namespace {
// The current implementation is naive: each thread writes to Out guarded by Mu.
// Perhaps we should replace this by something that disturbs performance less.
class JSONTracer : public EventTracer {
public:
  JSONTracer(llvm::raw_ostream &OS, bool Pretty)
      : Out(OS, Pretty ? 2 : 0), Start(std::chrono::system_clock::now()) {
    // The displayTimeUnit must be ns to avoid low-precision overlap
    // calculations!
    Out.objectBegin();
    Out.attribute("displayTimeUnit", "ns");
    Out.attributeBegin("traceEvents");
    Out.arrayBegin();
    rawEvent("M", llvm::json::Object{
                      {"name", "process_name"},
                      {"args", llvm::json::Object{{"name", "clangd"}}},
                  });
  }

  ~JSONTracer() {
    Out.arrayEnd();
    Out.attributeEnd();
    Out.objectEnd();
    Out.flush();
  }

  // We stash a Span object in the context. It will record the start/end,
  // and this also allows us to look up the parent Span's information.
  Context beginSpan(
      llvm::StringRef Name,
      llvm::function_ref<void(llvm::json::Object *)> AttachDetails) override {
    auto JS = std::make_unique<JSONSpan>(this, Name);
    AttachDetails(&JS->Args);
    return Context::current().derive(SpanKey, std::move(JS));
  }

  // Trace viewer requires each thread to properly stack events.
  // So we need to mark only duration that the span was active on the thread.
  // (Hopefully any off-thread activity will be connected by a flow event).
  // Record the end time here, but don't write the event: Args aren't ready yet.
  void endSpan() override {
    Context::current().getExisting(SpanKey)->markEnded();
  }

  void instant(llvm::StringRef Name, llvm::json::Object &&Args) override {
    captureThreadMetadata();
    jsonEvent("i",
              llvm::json::Object{{"name", Name}, {"args", std::move(Args)}});
  }

  // Record an event on the current thread. ph, pid, tid, ts are set.
  // Contents must be a list of the other JSON key/values.
  void jsonEvent(llvm::StringRef Phase, llvm::json::Object &&Contents,
                 uint64_t TID = llvm::get_threadid(), double Timestamp = 0) {
    Contents["ts"] = Timestamp ? Timestamp : timestamp();
    Contents["tid"] = int64_t(TID);
    std::lock_guard<std::mutex> Lock(Mu);
    rawEvent(Phase, Contents);
  }

private:
  class JSONSpan {
  public:
    JSONSpan(JSONTracer *Tracer, llvm::StringRef Name)
        : StartTime(Tracer->timestamp()), EndTime(0), Name(Name),
          TID(llvm::get_threadid()), Tracer(Tracer) {
      // ~JSONSpan() may run in a different thread, so we need to capture now.
      Tracer->captureThreadMetadata();

      // We don't record begin events here (and end events in the destructor)
      // because B/E pairs have to appear in the right order, which is awkward.
      // Instead we send the complete (X) event in the destructor.

      // If our parent was on a different thread, add an arrow to this span.
      auto *Parent = Context::current().get(SpanKey);
      if (Parent && *Parent && (*Parent)->TID != TID) {
        // If the parent span ended already, then show this as "following" it.
        // Otherwise show us as "parallel".
        double OriginTime = (*Parent)->EndTime;
        if (!OriginTime)
          OriginTime = (*Parent)->StartTime;

        auto FlowID = nextID();
        Tracer->jsonEvent(
            "s",
            llvm::json::Object{{"id", FlowID},
                               {"name", "Context crosses threads"},
                               {"cat", "mock_cat"}},
            (*Parent)->TID, (*Parent)->StartTime);
        Tracer->jsonEvent(
            "f",
            llvm::json::Object{{"id", FlowID},
                               {"bp", "e"},
                               {"name", "Context crosses threads"},
                               {"cat", "mock_cat"}},
            TID);
      }
    }

    ~JSONSpan() {
      // Finally, record the event (ending at EndTime, not timestamp())!
      Tracer->jsonEvent("X",
                        llvm::json::Object{{"name", std::move(Name)},
                                           {"args", std::move(Args)},
                                           {"dur", EndTime - StartTime}},
                        TID, StartTime);
    }

    // May be called by any thread.
    void markEnded() { EndTime = Tracer->timestamp(); }

    llvm::json::Object Args;

  private:
    static int64_t nextID() {
      static std::atomic<int64_t> Next = {0};
      return Next++;
    }

    double StartTime;
    std::atomic<double> EndTime; // Filled in by markEnded().
    std::string Name;
    uint64_t TID;
    JSONTracer *Tracer;
  };
  static Key<std::unique_ptr<JSONSpan>> SpanKey;

  // Record an event. ph and pid are set.
  // Contents must be a list of the other JSON key/values.
  void rawEvent(llvm::StringRef Phase,
                const llvm::json::Object &Event) /*REQUIRES(Mu)*/ {
    // PID 0 represents the clangd process.
    Out.object([&] {
      Out.attribute("pid", 0);
      Out.attribute("ph", Phase);
      for (const auto &KV : Event)
        Out.attribute(KV.first, KV.second);
    });
  }

  // If we haven't already, emit metadata describing this thread.
  void captureThreadMetadata() {
    uint64_t TID = llvm::get_threadid();
    std::lock_guard<std::mutex> Lock(Mu);
    if (ThreadsWithMD.insert(TID).second) {
      llvm::SmallString<32> Name;
      llvm::get_thread_name(Name);
      if (!Name.empty()) {
        rawEvent("M", llvm::json::Object{
                          {"tid", int64_t(TID)},
                          {"name", "thread_name"},
                          {"args", llvm::json::Object{{"name", Name}}},
                      });
      }
    }
  }

  double timestamp() {
    using namespace std::chrono;
    return duration<double, std::micro>(system_clock::now() - Start).count();
  }

  std::mutex Mu;
  llvm::json::OStream Out /*GUARDED_BY(Mu)*/;
  llvm::DenseSet<uint64_t> ThreadsWithMD /*GUARDED_BY(Mu)*/;
  const llvm::sys::TimePoint<> Start;
};

// We emit CSV as specified in RFC 4180: https://www.ietf.org/rfc/rfc4180.txt.
// \r\n line endings are used, cells with \r\n," are quoted, quotes are doubled.
class CSVMetricTracer : public EventTracer {
public:
  CSVMetricTracer(llvm::raw_ostream &Out) : Out(Out) {
    Start = std::chrono::steady_clock::now();

    Out.SetUnbuffered(); // We write each line atomically.
    Out << "Kind,Metric,Label,Value,Timestamp\r\n";
  }

  void record(const Metric &Metric, double Value,
              llvm::StringRef Label) override {
    assert(!needsQuote(Metric.Name));
    std::string QuotedLabel;
    if (needsQuote(Label))
      Label = QuotedLabel = quote(Label);
    uint64_t Micros = std::chrono::duration_cast<std::chrono::microseconds>(
                          std::chrono::steady_clock::now() - Start)
                          .count();
    std::lock_guard<std::mutex> Lock(Mu);
    Out << llvm::formatv("{0},{1},{2},{3:e},{4}.{5:6}\r\n",
                         typeName(Metric.Type), Metric.Name, Label, Value,
                         Micros / 1000000, Micros % 1000000);
  }

private:
  llvm::StringRef typeName(Metric::MetricType T) {
    switch (T) {
    case Metric::Value:
      return "v";
    case Metric::Counter:
      return "c";
    case Metric::Distribution:
      return "d";
    }
    llvm_unreachable("Unknown Metric::MetricType enum");
  }

  static bool needsQuote(llvm::StringRef Text) {
    // https://www.ietf.org/rfc/rfc4180.txt section 2.6
    return Text.find_first_of(",\"\r\n") != llvm::StringRef::npos;
  }

  std::string quote(llvm::StringRef Text) {
    std::string Result = "\"";
    for (char C : Text) {
      Result.push_back(C);
      if (C == '"')
        Result.push_back('"');
    }
    Result.push_back('"');
    return Result;
  }

private:
  std::mutex Mu;
  llvm::raw_ostream &Out /*GUARDED_BY(Mu)*/;
  std::chrono::steady_clock::time_point Start;
};

Key<std::unique_ptr<JSONTracer::JSONSpan>> JSONTracer::SpanKey;

EventTracer *T = nullptr;
} // namespace

Session::Session(EventTracer &Tracer) {
  assert(!T && "Resetting global tracer is not allowed.");
  T = &Tracer;
}

Session::~Session() { T = nullptr; }

std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
                                              bool Pretty) {
  return std::make_unique<JSONTracer>(OS, Pretty);
}

std::unique_ptr<EventTracer> createCSVMetricTracer(llvm::raw_ostream &OS) {
  return std::make_unique<CSVMetricTracer>(OS);
}

void log(const llvm::Twine &Message) {
  if (!T)
    return;
  T->instant("Log", llvm::json::Object{{"Message", Message.str()}});
}

bool enabled() { return T != nullptr; }

// The JSON object is event args (owned by context), if the tracer wants them.
static std::pair<Context, llvm::json::Object *>
makeSpanContext(llvm::Twine Name, const Metric &LatencyMetric) {
  if (!T)
    return std::make_pair(Context::current().clone(), nullptr);
  llvm::Optional<WithContextValue> WithLatency;
  using Clock = std::chrono::high_resolution_clock;
  WithLatency.emplace(llvm::make_scope_exit(
      [StartTime = Clock::now(), Name = Name.str(), &LatencyMetric] {
        LatencyMetric.record(
            std::chrono::duration_cast<std::chrono::milliseconds>(Clock::now() -
                                                                  StartTime)
                .count(),
            Name);
      }));
  llvm::json::Object *Args = nullptr;
  Context Ctx = T->beginSpan(
      Name.isSingleStringRef() ? Name.getSingleStringRef()
                               : llvm::StringRef(Name.str()),
      [&](llvm::json::Object *A) {
        assert(A && A->empty() && "Invalid AttachDetails() placeholder!");
        Args = A;
      });
  return std::make_pair(std::move(Ctx), Args);
}

// Fallback metric that measures latencies for spans without an explicit latency
// metric. Labels are span names.
constexpr Metric SpanLatency("span_latency", Metric::Distribution, "span_name");

// Span keeps a non-owning pointer to the args, which is how users access them.
// The args are owned by the context though. They stick around until the
// beginSpan() context is destroyed, when the tracing engine will consume them.
Span::Span(llvm::Twine Name) : Span(Name, SpanLatency) {}
Span::Span(llvm::Twine Name, const Metric &LatencyMetric)
    : Span(makeSpanContext(Name, LatencyMetric)) {}
Span::Span(std::pair<Context, llvm::json::Object *> Pair)
    : Args(Pair.second), RestoreCtx(std::move(Pair.first)) {}

Span::~Span() {
  if (T)
    T->endSpan();
}

void Metric::record(double Value, llvm::StringRef Label) const {
  if (!T)
    return;
  assert((LabelName.empty() == Label.empty()) &&
         "recording a measurement with inconsistent labeling");
  T->record(*this, Value, Label);
}

Context EventTracer::beginSpan(
    llvm::StringRef Name,
    llvm::function_ref<void(llvm::json::Object *)> AttachDetails) {
  return Context::current().clone();
}
} // namespace trace
} // namespace clangd
} // namespace clang
