/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include <chrono>
#include <thread>

// This source file is built in two ways:
// 1. As part of the regular GN build, against standard includes.
// 2. To test that the amalgmated SDK works, against the perfetto.h source.

#ifdef PERFETTO_AMALGAMATED_SDK_TEST
#include "perfetto.h"
#else
#include "perfetto/tracing.h"
#include "protos/perfetto/config/gpu/gpu_counter_config.pbzero.h"
#include "protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h"
#include "protos/perfetto/trace/test_event.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
#endif

// Deliberately not pulling any non-public perfetto header to spot accidental
// header public -> non-public dependency while building this file.
namespace {
class MyDataSource : public perfetto::DataSource<MyDataSource> {
 public:
  void OnSetup(const SetupArgs& args) override {
    // This can be used to access the domain-specific DataSourceConfig, via
    // args.config->xxx_config_raw().
    const std::string& config_raw = args.config->gpu_counter_config_raw();
    perfetto::protos::pbzero::GpuCounterConfig::Decoder config(config_raw);

    int sample_period = 0;
    if (config.has_counter_period_ns())
      sample_period = static_cast<int>(config.counter_period_ns());

    std::vector<uint32_t> counter_ids;
    for (auto it = config.counter_ids(); it; ++it) {
      uint32_t counter_id = it->as_uint32();
      if (counter_id > 0) {
        counter_ids.push_back(counter_id);
      }
    }

    PERFETTO_ILOG(
        "OnSetup called, name: %s,"
        "counter_period_ms: %d, tracing_session_id: %" PRIu64
        " num counters: %zu",
        args.config->name().c_str(), int(sample_period / 1000000),
        args.config->tracing_session_id(), counter_ids.size());
  }

  void OnStart(const StartArgs&) override { PERFETTO_ILOG("OnStart called"); }

  void OnStop(const StopArgs& stop_args) override {
    PERFETTO_ILOG("OnStop called");

    auto stop_closure = stop_args.HandleStopAsynchronously();

    // It is possible to trace on stop as well, but doing so requires manually
    // calling Flush() at the end.
    MyDataSource::Trace([](MyDataSource::TraceContext ctx) {
      PERFETTO_LOG("Tracing lambda called while stopping");
      // This block here is to auto-finalize the packet before calling Flush.
      {
        auto packet = ctx.NewTracePacket();
        packet->set_timestamp(999);
      }
      ctx.Flush();
    });

    stop_closure();
  }
};

}  // namespace

PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(MyDataSource);
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MyDataSource);

int main() {
  perfetto::TracingInitArgs args;
  args.backends = perfetto::kSystemBackend;
  perfetto::Tracing::Initialize(args);

  // DataSourceDescriptor can be used to advertise domain-specific features.
  perfetto::DataSourceDescriptor dsd;
  dsd.set_name("com.example.mytrace");
  MyDataSource::Register(dsd);

  for (;;) {
    MyDataSource::Trace([](MyDataSource::TraceContext ctx) {
      PERFETTO_LOG("Tracing lambda called");
      auto packet = ctx.NewTracePacket();
      packet->set_timestamp(42);
      auto* gpu_packet = packet->set_gpu_counter_event();
      auto* cnt = gpu_packet->add_counters();
      cnt->set_counter_id(1);
    });
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
}
