// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>

#include <array>
#include <memory>

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <trace-engine/context.h>
#include <trace-engine/handler.h>
#include <trace-engine/types.h>
#include <trace-provider/handler.h>
#include <trace-test-utils/compare_records.h>
#include <trace-test-utils/read_records.h>
#include <unittest/unittest.h>

#include "trace-vthread/event_vthread.h"

// Helper macros for writing tests.
#define STR_ARGS1 "k1", TA_STRING("v1")
#define STR_ARGS4 \
  "k1", TA_STRING("v1"), "k2", TA_STRING("v2"), "k3", TA_STRING("v3"), "k4", TA_STRING("v4")

class TraceFixture : private trace::TraceHandler {
 public:
  static constexpr trace_buffering_mode_t kBufferingMode = TRACE_BUFFERING_MODE_ONESHOT;

  static constexpr size_t kBufferSize = 1024 * 1024;

  TraceFixture() { buffer_.reset(new std::array<uint8_t, kBufferSize>); }

  bool StartTracing() {
    zx_status_t init_status = trace_engine_initialize(loop_.dispatcher(), this, kBufferingMode,
                                                      buffer_->data(), buffer_->size());
    zx_status_t start_status = trace_engine_start(TRACE_START_CLEAR_ENTIRE_BUFFER);
    return init_status == ZX_OK && start_status == ZX_OK;
  }

  bool StopTracing() {
    trace_engine_terminate();
    loop_.RunUntilIdle();
    return true;
  }

  bool CompareBuffer(const char* expected) {
    BEGIN_HELPER;
    fbl::Vector<trace::Record> records;
    ASSERT_TRUE(trace_testing::ReadRecords(buffer_->data(), buffer_->size(), &records));
    ASSERT_TRUE(trace_testing::CompareBuffer(records, expected));
    END_HELPER;
  }

 private:
  async::Loop loop_{&kAsyncLoopConfigAttachToCurrentThread};

  std::unique_ptr<std::array<uint8_t, kBufferSize>> buffer_;
};

bool TestVthreadDurationBegin() {
  TraceFixture fixture;

  BEGIN_TEST;

  ASSERT_TRUE(fixture.StartTracing());

  TRACE_VTHREAD_DURATION_BEGIN("+enabled", "name", "virtual-thread", 1u, zx_ticks_get());
  TRACE_VTHREAD_DURATION_BEGIN("+enabled", "name", "virtual-thread", 1u, zx_ticks_get(), STR_ARGS1);
  TRACE_VTHREAD_DURATION_BEGIN("+enabled", "name", "virtual-thread", 1u, zx_ticks_get(), STR_ARGS4);

  ASSERT_TRUE(fixture.StopTracing());

  ASSERT_TRUE(
      fixture.CompareBuffer("\
String(index: 1, \"+enabled\")\n\
String(index: 2, \"process\")\n\
KernelObject(koid: <>, type: thread, name: \"virtual-thread\", {process: koid(<>)})\n\
Thread(index: 1, <>)\n\
String(index: 3, \"name\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", DurationBegin, {})\n\
String(index: 4, \"k1\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", DurationBegin, {k1: string(\"v1\")})\n\
String(index: 5, \"k2\")\n\
String(index: 6, \"k3\")\n\
String(index: 7, \"k4\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", DurationBegin, {k1: string(\"v1\"), k2: string(\"v2\"), k3: string(\"v3\"), k4: string(\"v4\")})\n\
"));

  END_TEST;
}

bool TestVthreadDurationEnd() {
  TraceFixture fixture;

  BEGIN_TEST;

  ASSERT_TRUE(fixture.StartTracing());

  TRACE_VTHREAD_DURATION_END("+enabled", "name", "virtual-thread", 1u, zx_ticks_get());
  TRACE_VTHREAD_DURATION_END("+enabled", "name", "virtual-thread", 1u, zx_ticks_get(), STR_ARGS1);
  TRACE_VTHREAD_DURATION_END("+enabled", "name", "virtual-thread", 1u, zx_ticks_get(), STR_ARGS4);

  ASSERT_TRUE(fixture.StopTracing());

  ASSERT_TRUE(
      fixture.CompareBuffer("\
String(index: 1, \"+enabled\")\n\
String(index: 2, \"process\")\n\
KernelObject(koid: <>, type: thread, name: \"virtual-thread\", {process: koid(<>)})\n\
Thread(index: 1, <>)\n\
String(index: 3, \"name\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", DurationEnd, {})\n\
String(index: 4, \"k1\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", DurationEnd, {k1: string(\"v1\")})\n\
String(index: 5, \"k2\")\n\
String(index: 6, \"k3\")\n\
String(index: 7, \"k4\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", DurationEnd, {k1: string(\"v1\"), k2: string(\"v2\"), k3: string(\"v3\"), k4: string(\"v4\")})\n\
"));

  END_TEST;
}

bool TestVthreadFlowBegin() {
  TraceFixture fixture;

  BEGIN_TEST;

  ASSERT_TRUE(fixture.StartTracing());

  TRACE_VTHREAD_FLOW_BEGIN("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get());
  TRACE_VTHREAD_FLOW_BEGIN("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get(), STR_ARGS1);
  TRACE_VTHREAD_FLOW_BEGIN("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get(), STR_ARGS4);

  ASSERT_TRUE(fixture.StopTracing());

  ASSERT_TRUE(
      fixture.CompareBuffer("\
String(index: 1, \"+enabled\")\n\
String(index: 2, \"process\")\n\
KernelObject(koid: <>, type: thread, name: \"virtual-thread\", {process: koid(<>)})\n\
Thread(index: 1, <>)\n\
String(index: 3, \"name\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowBegin(id: 2), {})\n\
String(index: 4, \"k1\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowBegin(id: 2), {k1: string(\"v1\")})\n\
String(index: 5, \"k2\")\n\
String(index: 6, \"k3\")\n\
String(index: 7, \"k4\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowBegin(id: 2), {k1: string(\"v1\"), k2: string(\"v2\"), k3: string(\"v3\"), k4: string(\"v4\")})\n\
"));

  END_TEST;
}

bool TestVthreadFlowStep() {
  TraceFixture fixture;

  BEGIN_TEST;

  ASSERT_TRUE(fixture.StartTracing());

  TRACE_VTHREAD_FLOW_STEP("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get());
  TRACE_VTHREAD_FLOW_STEP("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get(), STR_ARGS1);
  TRACE_VTHREAD_FLOW_STEP("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get(), STR_ARGS4);

  ASSERT_TRUE(fixture.StopTracing());

  ASSERT_TRUE(
      fixture.CompareBuffer("\
String(index: 1, \"+enabled\")\n\
String(index: 2, \"process\")\n\
KernelObject(koid: <>, type: thread, name: \"virtual-thread\", {process: koid(<>)})\n\
Thread(index: 1, <>)\n\
String(index: 3, \"name\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowStep(id: 2), {})\n\
String(index: 4, \"k1\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowStep(id: 2), {k1: string(\"v1\")})\n\
String(index: 5, \"k2\")\n\
String(index: 6, \"k3\")\n\
String(index: 7, \"k4\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowStep(id: 2), {k1: string(\"v1\"), k2: string(\"v2\"), k3: string(\"v3\"), k4: string(\"v4\")})\n\
"));

  END_TEST;
}

bool TestVthreadFlowEnd() {
  TraceFixture fixture;

  BEGIN_TEST;

  ASSERT_TRUE(fixture.StartTracing());

  TRACE_VTHREAD_FLOW_END("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get());
  TRACE_VTHREAD_FLOW_END("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get(), STR_ARGS1);
  TRACE_VTHREAD_FLOW_END("+enabled", "name", "virtual-thread", 1u, 2u, zx_ticks_get(), STR_ARGS4);

  ASSERT_TRUE(fixture.StopTracing());

  ASSERT_TRUE(
      fixture.CompareBuffer("\
String(index: 1, \"+enabled\")\n\
String(index: 2, \"process\")\n\
KernelObject(koid: <>, type: thread, name: \"virtual-thread\", {process: koid(<>)})\n\
Thread(index: 1, <>)\n\
String(index: 3, \"name\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowEnd(id: 2), {})\n\
String(index: 4, \"k1\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowEnd(id: 2), {k1: string(\"v1\")})\n\
String(index: 5, \"k2\")\n\
String(index: 6, \"k3\")\n\
String(index: 7, \"k4\")\n\
Event(ts: <>, pt: <>, category: \"+enabled\", name: \"name\", FlowEnd(id: 2), {k1: string(\"v1\"), k2: string(\"v2\"), k3: string(\"v3\"), k4: string(\"v4\")})\n\
"));

  END_TEST;
}

BEGIN_TEST_CASE(event_thread_tests)
RUN_TEST(TestVthreadDurationBegin)
RUN_TEST(TestVthreadDurationEnd)
RUN_TEST(TestVthreadFlowBegin)
RUN_TEST(TestVthreadFlowStep)
RUN_TEST(TestVthreadFlowEnd)
END_TEST_CASE(event_thread_tests)
