// Copyright 2013 The Flutter 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 FLUTTER_SHELL_PROFILING_SAMPLING_PROFILER_H_
#define FLUTTER_SHELL_PROFILING_SAMPLING_PROFILER_H_

#include <functional>
#include <memory>
#include <optional>
#include <string>

#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/task_runner.h"
#include "flutter/fml/trace_event.h"

namespace flutter {

/**
 * @brief CPU usage stats. `num_threads` is the number of threads owned by the
 * process. It is to be noted that this is not per shell, there can be multiple
 * shells within the process. `total_cpu_usage` is the percentage (between [0,
 * 100]) cpu usage of the application. This is across all the cores, for example
 * an application using 100% of all the core will report `total_cpu_usage` as
 * `100`, if it has 100% across 2 cores and 0% across the other cores, embedder
 * must report `total_cpu_usage` as `50`.
 */
struct CpuUsageInfo {
  uint32_t num_threads;
  double total_cpu_usage;
};

/**
 * @brief Memory usage stats. `dirty_memory_usage` is the memory usage (in
 * MB) such that the app uses its physical memory for dirty memory. Dirty memory
 * is the memory data that cannot be paged to disk. `owned_shared_memory_usage`
 * is the memory usage (in MB) such that the app uses its physical memory for
 * shared memory, including loaded frameworks and executables. On iOS, it's
 * `physical memory - dirty memory`.
 */
struct MemoryUsageInfo {
  double dirty_memory_usage;
  double owned_shared_memory_usage;
};

/**
 * @brief Polled information related to the usage of the GPU.
 */
struct GpuUsageInfo {
  double percent_usage;
};

/**
 * @brief Container for the metrics we collect during each run of `Sampler`.
 * This currently holds `CpuUsageInfo` and `MemoryUsageInfo` but the intent
 * is to expand it to other metrics.
 *
 * @see flutter::Sampler
 */
struct ProfileSample {
  std::optional<CpuUsageInfo> cpu_usage;
  std::optional<MemoryUsageInfo> memory_usage;
  std::optional<GpuUsageInfo> gpu_usage;
};

/**
 * @brief Sampler is run during `SamplingProfiler::SampleRepeatedly`. Each
 * platform should implement its version of a `Sampler` if they decide to
 * participate in gathering profiling metrics.
 *
 * @see flutter::SamplingProfiler::SampleRepeatedly
 */
using Sampler = std::function<ProfileSample(void)>;

/**
 * @brief a Sampling Profiler that runs peridically and calls the `Sampler`
 * which servers as a value function to gather various profiling metrics as
 * represented by `ProfileSample`. These profiling metrics are then posted to
 * the observatory timeline.
 *
 */
class SamplingProfiler {
 public:
  /**
   * @brief Construct a new Sampling Profiler object
   *
   * @param thread_label observatory prefix to be set for the profiling task
   * runner.
   * @param profiler_task_runner the task runner to service sampling requests.
   * @param sampler the value function to collect the profiling metrics.
   * @param num_samples_per_sec number of times you wish to run the sampler per
   * second.
   *
   * @see fml::TaskRunner
   */
  SamplingProfiler(const char* thread_label,
                   fml::RefPtr<fml::TaskRunner> profiler_task_runner,
                   Sampler sampler,
                   int num_samples_per_sec);

  ~SamplingProfiler();

  /**
   * @brief Starts the SamplingProfiler by triggering `SampleRepeatedly`.
   *
   */
  void Start();

  void Stop();

 private:
  const std::string thread_label_;
  const fml::RefPtr<fml::TaskRunner> profiler_task_runner_;
  const Sampler sampler_;
  const uint32_t num_samples_per_sec_;
  bool is_running_ = false;
  std::atomic<fml::AutoResetWaitableEvent*> shutdown_latch_ = nullptr;

  void SampleRepeatedly(fml::TimeDelta task_delay) const;

  /**
   * @brief This doesn't update the underlying OS thread name for the thread
   * backing `profiler_task_runner_`. Instead, this is just additional metadata
   * for the Observatory to show the thread name of the isolate.
   *
   */
  void UpdateObservatoryThreadName() const;

  FML_DISALLOW_COPY_AND_ASSIGN(SamplingProfiler);
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PROFILING_SAMPLING_PROFILER_H_
