// Copyright 2017 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 "trace-test-utils/fixture.h"

#include <regex.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <utility>

#include <zircon/assert.h>

#include <fbl/algorithm.h>
#include <fbl/array.h>
#include <fbl/string.h>
#include <fbl/string_buffer.h>
#include <fbl/vector.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/zx/event.h>
#include <trace-provider/handler.h>
#include <trace-reader/reader.h>
#include <trace-reader/reader_internal.h>
#include <trace-test-utils/compare_records.h>
#include <trace-test-utils/read_records.h>

namespace {

class Fixture : private trace::TraceHandler {
 public:
  Fixture(attach_to_thread_t attach_to_thread, trace_buffering_mode_t mode, size_t buffer_size)
      : attach_to_thread_(attach_to_thread),
        loop_(attach_to_thread == kAttachToThread ? &kAsyncLoopConfigAttachToCurrentThread
                                                  : &kAsyncLoopConfigNoAttachToCurrentThread),
        buffering_mode_(mode),
        buffer_(new uint8_t[buffer_size], buffer_size) {
    zx_status_t status = zx::event::create(0u, &trace_stopped_);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    status = zx::event::create(0u, &buffer_full_);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    ResetEngineState();
  }

  ~Fixture() {
    TerminateEngine();
    WaitEngineStopped();
  }

  void ResetEngineState() {
    // The engine may be started/stopped multiple times.
    // Reset related state tracking vars each time.
    disposition_ = ZX_ERR_INTERNAL;
    observed_stopped_callback_ = false;
    ResetBufferFullNotification();
  }

  void InitializeEngine() {
    ResetEngineState();
    if (attach_to_thread_ == kNoAttachToThread) {
      loop_.StartThread("trace test");
    }

    zx_status_t status = trace_engine_initialize(loop_.dispatcher(), this, buffering_mode_,
                                                 buffer_.data(), buffer_.size());
    ZX_DEBUG_ASSERT_MSG(status == ZX_OK, "status=%d", status);
  }

  void StartEngine() {
    ResetEngineState();
    zx_status_t status = trace_engine_start(TRACE_START_CLEAR_ENTIRE_BUFFER);
    ZX_DEBUG_ASSERT_MSG(status == ZX_OK, "status=%d", status);
  }

  void StopEngine() { trace_engine_stop(ZX_OK); }

  void TerminateEngine() { trace_engine_terminate(); }

  void WaitEngineStopped() {
    zx_status_t status;
    while (trace_state() != TRACE_STOPPED) {
      if (attach_to_thread_ == kNoAttachToThread) {
        status =
            trace_stopped_.wait_one(ZX_EVENT_SIGNALED, zx::deadline_after(zx::msec(100)), nullptr);
        ZX_DEBUG_ASSERT_MSG(status == ZX_OK || status == ZX_ERR_TIMED_OUT, "status=%d", status);
      } else {
        // Finish up any remaining tasks. The engine may have queued some.
        status = loop_.RunUntilIdle();
        ZX_DEBUG_ASSERT_MSG(status == ZX_OK, "status=%d", status);
      }
    }
  }

  void Shutdown() {
    // Shut down the loop (implicitly joins the thread we started
    // earlier). When this completes we know the trace engine is
    // really stopped.
    loop_.Shutdown();

    ZX_DEBUG_ASSERT(observed_stopped_callback_);
  }

  void InitializeAndStartTracing() {
    InitializeEngine();
    StartEngine();
  }

  void StopAndTerminateTracing(bool hard_shutdown) {
    // Asynchronously stop the engine.
    // If we're performing a hard shutdown, skip this step and begin immediately
    // tearing down the loop.  The trace engine should stop itself.
    if (!hard_shutdown) {
      StopEngine();
      WaitEngineStopped();
      TerminateEngine();
    }

    Shutdown();
  }

  bool WaitBufferFullNotification() {
    auto status =
        buffer_full_.wait_one(ZX_EVENT_SIGNALED, zx::deadline_after(zx::msec(1000)), nullptr);
    buffer_full_.signal(ZX_EVENT_SIGNALED, 0u);
    return status == ZX_OK;
  }

  async::Loop& loop() { return loop_; }

  zx_status_t disposition() const { return disposition_; }

  bool observed_notify_buffer_full_callback() const {
    return observed_notify_buffer_full_callback_;
  }

  bool observed_buffer_full_wrapped_count() const { return observed_buffer_full_wrapped_count_; }

  bool observed_buffer_full_durable_data_end() const {
    return observed_buffer_full_durable_data_end_;
  }

  void ResetBufferFullNotification() {
    observed_notify_buffer_full_callback_ = false;
    observed_buffer_full_wrapped_count_ = 0;
    observed_buffer_full_durable_data_end_ = 0;
  }

  bool ReadRecords(fbl::Vector<trace::Record>* out_records) {
    return trace_testing::ReadRecords(buffer_.data(), buffer_.size(), out_records);
  }

 private:
  bool IsCategoryEnabled(const char* category) override {
    // All categories which begin with + are enabled.
    return category[0] == '+';
  }

  void TraceStopped(zx_status_t disposition) override {
    ZX_DEBUG_ASSERT(!observed_stopped_callback_);
    observed_stopped_callback_ = true;
    disposition_ = disposition;

    trace_stopped_.signal(0u, ZX_EVENT_SIGNALED);

    // The normal provider support does "delete this" here.
    // We don't need nor want it as we still have to verify the results.
  }

  void NotifyBufferFull(uint32_t wrapped_count, uint64_t durable_data_end) override {
    observed_notify_buffer_full_callback_ = true;
    observed_buffer_full_wrapped_count_ = wrapped_count;
    observed_buffer_full_durable_data_end_ = durable_data_end;
    buffer_full_.signal(0u, ZX_EVENT_SIGNALED);
  }

  attach_to_thread_t attach_to_thread_;
  async::Loop loop_;
  trace_buffering_mode_t buffering_mode_;
  fbl::Array<uint8_t> buffer_;
  zx_status_t disposition_;
  zx::event trace_stopped_;
  zx::event buffer_full_;
  bool observed_stopped_callback_;
  bool observed_notify_buffer_full_callback_;
  uint32_t observed_buffer_full_wrapped_count_;
  uint64_t observed_buffer_full_durable_data_end_;
};

Fixture* g_fixture{nullptr};

}  // namespace

void fixture_set_up(attach_to_thread_t attach_to_thread, trace_buffering_mode_t mode,
                    size_t buffer_size) {
  ZX_DEBUG_ASSERT(!g_fixture);
  g_fixture = new Fixture(attach_to_thread, mode, buffer_size);
}

void fixture_tear_down(void) {
  ZX_DEBUG_ASSERT(g_fixture);
  delete g_fixture;
  g_fixture = nullptr;
}

void fixture_initialize_engine() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->InitializeEngine();
}

void fixture_start_engine() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->StartEngine();
}

void fixture_stop_engine() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->StopEngine();
}

void fixture_terminate_engine() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->TerminateEngine();
}

void fixture_wait_engine_stopped(void) {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->WaitEngineStopped();
}

void fixture_shutdown() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->Shutdown();
}

void fixture_initialize_and_start_tracing() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->InitializeAndStartTracing();
}

void fixture_stop_and_terminate_tracing() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->StopAndTerminateTracing(false);
}

void fixture_stop_and_terminate_tracing_hard() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->StopAndTerminateTracing(true);
}

async_loop_t* fixture_async_loop(void) {
  ZX_DEBUG_ASSERT(g_fixture);
  return g_fixture->loop().loop();
}

zx_status_t fixture_get_disposition(void) {
  ZX_DEBUG_ASSERT(g_fixture);
  return g_fixture->disposition();
}

bool fixture_wait_buffer_full_notification() {
  ZX_DEBUG_ASSERT(g_fixture);
  return g_fixture->WaitBufferFullNotification();
}

uint32_t fixture_get_buffer_full_wrapped_count() {
  ZX_DEBUG_ASSERT(g_fixture);
  return g_fixture->observed_buffer_full_wrapped_count();
}

void fixture_reset_buffer_full_notification() {
  ZX_DEBUG_ASSERT(g_fixture);
  g_fixture->ResetBufferFullNotification();
}

bool fixture_read_records(fbl::Vector<trace::Record>* out_records) {
  return g_fixture->ReadRecords(out_records);
}

bool fixture_compare_raw_records(const fbl::Vector<trace::Record>& records, size_t start_record,
                                 size_t max_num_records, const char* expected) {
  return trace_testing::CompareRecords(records, start_record, max_num_records, expected);
}

bool fixture_compare_n_records(size_t max_num_records, const char* expected,
                               fbl::Vector<trace::Record>* out_records,
                               size_t* out_leading_to_skip) {
  ZX_DEBUG_ASSERT(g_fixture);

  g_fixture->StopAndTerminateTracing(false);

  if (!fixture_read_records(out_records)) {
    return false;
  }

  return trace_testing::ComparePartialBuffer(*out_records, max_num_records, expected,
                                             out_leading_to_skip);
}

bool fixture_compare_records(const char* expected) {
  fbl::Vector<trace::Record> records;
  return fixture_compare_n_records(SIZE_MAX, expected, &records, nullptr);
}

void fixture_snapshot_buffer_header(trace_buffer_header* header) {
  auto context = trace::TraceProlongedContext::Acquire();
  trace_context_snapshot_buffer_header_internal(context.get(), header);
}
