#ifndef PLS_INTERNAL_PROFILING_DAG_NODE_H_
#define PLS_INTERNAL_PROFILING_DAG_NODE_H_

#include "pls/internal/base/system_details.h"

#include <memory>
#include <list>
#include <iostream>
#include <chrono>

namespace pls::internal::profiling {

struct dag_node {
  using clock = std::chrono::steady_clock;
  using measurement_resolution = std::chrono::nanoseconds;
  using display_resolution = std::chrono::microseconds;
  static unsigned long m_to_d(unsigned long duration) {
    measurement_resolution measurement_duration{duration};
    return std::chrono::duration_cast<display_resolution>(measurement_duration).count();
  }

  dag_node(unsigned spawning_thread_id) : spawning_thread_id_{spawning_thread_id} {};

  unsigned spawning_thread_id_;
  unsigned long max_memory_{0};
  unsigned long total_runtime_{0};

  std::unique_ptr<dag_node> next_node_;
  std::list<dag_node> child_nodes_;

  base::system_details::pointer_t node_print_id() {
    return reinterpret_cast<base::system_details::pointer_t >(this);
  }

  void dag_compact();
  void dag_print(std::ostream &stream, unsigned rank, bool capture_memory, bool capture_time);
  unsigned dag_max_memory();
  unsigned long dag_total_user_time();
  unsigned long dag_critical_path();
  unsigned long dag_depth();
};

}

#endif //PLS_INTERNAL_PROFILING_DAG_NODE_H_
