// 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.

#ifndef GARNET_BIN_TRACE_TESTS_INTEGRATION_TEST_UTILS_H_
#define GARNET_BIN_TRACE_TESTS_INTEGRATION_TEST_UTILS_H_

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/trace-provider/provider.h>
#include <lib/zx/time.h>
#include <stddef.h>

#include <memory>
#include <string>

#include <trace-reader/reader.h>

#include "garnet/bin/trace/options.h"

// Category for events generated by |WriteTestEvents()|.
#define CATEGORY_NAME "trace:test"

namespace tracing {
namespace test {

using TestRunner = bool(size_t buffer_size_in_mb, const std::string& buffering_mode);
using TestVerifier = bool(size_t buffer_size_in_mb, const std::string& buffering_mode,
                          const std::string& test_output_file);

struct IntegrationTest {
  const char* name;
  TestRunner* run;
  TestVerifier* verify;
};

// When emitting a small fixed number of events, emit this amount.
// We don't need many, and certainly not so much that we overflow the buffer:
// Here we can verify we got precisely the number of events we expected.
constexpr size_t kNumSimpleTestEvents = 10;

// If things go really wrong a large number of error messages can appear,
// which is annoying. Don't print more than this amount.
constexpr size_t kMaxErrorCount = 20;

// This file is a relative path, from the tmp directory.
constexpr char kRelativeOutputFilePath[] = "test.trace";

// Smallest buffer possible, 1MB.
constexpr const char kBufferSizeArg[] = "--buffer-size=1";

// Category used by |WriteTestEvents()|.
constexpr const char kWriteTestEventsCategoryName[] = "trace:test";

// Event name used by |WriteTestEvents()| instant events.
constexpr const char kWriteTestEventsInstantEventName[] = "instant";

// When waiting for tracing to start, wait this long.
constexpr zx::duration kStartTimeout{zx::sec(60)};

// When waiting for tracing to stop, wait this long.
constexpr zx::duration kStopTimeout{zx::sec(60)};

// Given |test_name| return its |IntegrationTest| spec.
const IntegrationTest* LookupTest(const std::string& test_name);

// Create a provider.
// On success an indicator of whether tracing has already started is stored in
// |*out_already_started|. This does not mean tracing has started in this provider; this provider
// must still wait for the Start() request from trace-manager.
// This is intended to be accompanied by a call to |WaitForTracingToStart()|.
// The two are split out as the details of waiting depend on the loop being used (e.g., is it
// running in a foreground thread or background thread?).
bool CreateProviderSynchronously(async::Loop& loop, const char* name,
                                 std::unique_ptr<trace::TraceProvider>* out_provider,
                                 bool* out_already_started);

// Simplified version that calls both |CreateProviderSynchronously(),WaitForTracingToStart()|.
bool CreateProviderSynchronouslyAndWait(async::Loop& loop, const char* name,
                                        std::unique_ptr<trace::TraceProvider>* out_provider);

// Emit |num_iterations| records that |VerifyTestEvents()| knows how to test.
void WriteTestEvents(size_t num_records);

// Return true if |record| was emitted by |WriteTestEvents()|.
bool IsWriteTestEvent(const trace::Record& record);

// Verify a trace generated with |WriteTestEvents()| in json format.
// Returns a boolean indicating success.
// On success returns the number of events found in |*out_num_events|.
bool VerifyTestEventsFromJson(const std::string& test_output_file, size_t* out_num_events);

// Verify a trace generated with |WriteTestEvents()| in binary fxt format.
// Returns a boolean indicating success.
bool VerifyTestEventsFromFxt(const std::string& test_output_file,
                             trace::TraceReader::RecordConsumer record_consumer);

// Write as many records as we can to ensure a buffer of size
// |buffer_size_in_mb| is full, and fill it |num_times|.
void FillBuffer(size_t num_times, size_t buffer_size_in_mb);

// Verify the trace generated by |FillBuffer()|.
// Returns a boolean indicating success.
bool VerifyFullBuffer(const std::string& test_output_file, tracing::BufferingMode buffering_mode,
                      size_t buffer_size_in_mb);

// Wait for tracing to start or |timeout|.
// Basically this means waiting for the Start() request which contains the trace buffer (as a vmo)
// and other things.
// |loop| must be idle and not have any background threads.
// Returns true on success.
bool WaitForTracingToStart(async::Loop& loop, zx::duration timeout);

}  // namespace test
}  // namespace tracing

#endif  // GARNET_BIN_TRACE_TESTS_INTEGRATION_TEST_UTILS_H_
