/*
 * Copyright (C) 2020 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.
 */

// This example demonstrates system-wide tracing with Perfetto.
//
// 1). To use it, first build the `tracebox` and this file. The tracebox will
// internally build tracing service (traced, which is long running
// process / daemon ) and perfetto consumer client, and many other perfetto
// tracing related tools.
// `ninja -C out/default/ tracebox example_system_wide`
//
// 2). Run traced (long running process), and open another terminal tab.
// `./out/default/tracebox traced`
//
// 3). Run this file. This is main application to trace.
// `./out/default/example_system_wide`
//
// 4). Use perfetto client to start a session and record trace in a file.
// `./out/default/tracebox perfetto -c /tmp/trace_config.txt --txt
//      -o /tmp/trace_output`
//
// but before running that command, put following trace config (protobuf config)
// in a file named `/tmp/trace_config.txt`
// This can also be copied from: https://pastebin.com/embed_iframe/ufmtBBuq
// ---------------------
// buffers: {
//     size_kb: 63488
// }
// data_sources: {
//     config {
//         name: "track_event"
//     }
// }
// duration_ms: 10000
// ---------------------
// After running the command above, trace will be saved in `/tmp/trace_output`
// file. It is a binary content. We can read it by running:
// `./tools/traceconv text /tmp/trace_output`
// Or we can use "Open Trace File" option in the perfetto UI
// (https://ui.perfetto.dev)
//
// Learn More:
// https://perfetto.dev/docs/quickstart/linux-tracing#capturing-a-trace

#include "trace_categories.h"

#include <chrono>
#include <condition_variable>
#include <fstream>
#include <thread>

namespace {

class Observer : public perfetto::TrackEventSessionObserver {
 public:
  Observer() { perfetto::TrackEvent::AddSessionObserver(this); }
  ~Observer() override { perfetto::TrackEvent::RemoveSessionObserver(this); }

  void OnStart(const perfetto::DataSourceBase::StartArgs&) override {
    std::unique_lock<std::mutex> lock(mutex);
    cv.notify_one();
  }

  void WaitForTracingStart() {
    PERFETTO_LOG("Waiting for tracing to start...");
    std::unique_lock<std::mutex> lock(mutex);
    cv.wait(lock, [] { return perfetto::TrackEvent::IsEnabled(); });
    PERFETTO_LOG("Tracing started");
  }

  std::mutex mutex;
  std::condition_variable cv;
};

void InitializePerfetto() {
  perfetto::TracingInitArgs args;
  // The backends determine where trace events are recorded. For this example we
  // are going to use the system-wide tracing service, so that we can see our
  // app's events in context with system profiling information.
  args.backends = perfetto::kSystemBackend;

  perfetto::Tracing::Initialize(args);
  perfetto::TrackEvent::Register();
}

void DrawPlayer(int player_number) {
  TRACE_EVENT("rendering", "DrawPlayer", "player_number", player_number);
  // Sleep to simulate a long computation.
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
}

void DrawGame() {
  TRACE_EVENT("rendering", "DrawGame");
  DrawPlayer(1);
  DrawPlayer(2);
}

}  // namespace

int main(int, const char**) {
  InitializePerfetto();

  Observer observer;
  observer.WaitForTracingStart();

  // Simulate some work that emits trace events.
  // Note that we don't start and stop tracing here; for system-wide tracing
  // this needs to be done through the "perfetto" command line tool or the
  // Perfetto UI (https://ui.perfetto.dev).
  DrawGame();

  // Make sure the last event is closed for this example.
  perfetto::TrackEvent::Flush();

  return 0;
}
