#include "tlbmc/trace/tracer.h"

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <string>

#include "google/protobuf/duration.pb.h"
#include "absl/base/no_destructor.h"
#include "absl/time/time.h"
#include "tlbmc/time/time.h"
#include "trace.pb.h"

namespace milotic_tlbmc {

void Tracer::AddDatapoint(const std::string& keyword, absl::Time timestamp,
                          bool repeated) {
  std::size_t order = 0;
  if (auto it = keyword_to_order_.find(keyword);
      it != keyword_to_order_.end()) {
    order = it->second;
  } else {
    order = keyword_to_order_.size();
    keyword_to_order_[keyword] = order;
  }
  CheckPoint checkpoint = {
      .order = order,
      .keyword = keyword,
      .repeated = repeated,
  };
  datapoints_[checkpoint].push_back(timestamp);
}

void Tracer::AddRepeatedDatapoint(const std::string& keyword,
                                  absl::Time timestamp) {
  if (!enabled_) {
    return;
  }
  AddDatapoint(keyword, timestamp, /*repeated=*/true);
}

void Tracer::AddOneOffDatapoint(const std::string& keyword,
                                absl::Time timestamp) {
  if (!enabled_) {
    return;
  }
  AddDatapoint(keyword, timestamp, /*repeated=*/false);
}

void Tracer::Clear() {
  datapoints_.clear();
  keyword_to_order_.clear();
}

Traces Tracer::Dump() const {
  Traces traces;
  for (auto it = datapoints_.begin(); it != datapoints_.end(); ++it) {
    if (it == datapoints_.begin()) {
      continue;
    }
    auto prev = std::prev(it);
    if (prev->first.repeated != it->first.repeated) {
      continue;
    }
    Trace trace;
    trace.set_from_checkpoint(prev->first.keyword);
    trace.set_to_checkpoint(it->first.keyword);

    absl::Duration total_duration = absl::ZeroDuration();
    std::size_t count = std::min(it->second.size(), prev->second.size());
    std::size_t index_it = it->second.size();
    std::size_t index_prev = prev->second.size();
    while (index_it >= 1 && index_prev >= 1) {
      total_duration += it->second[index_it - 1] - prev->second[index_prev - 1];
      --index_prev;
      --index_it;
    }
    absl::Duration average_duration = total_duration / count;
    *trace.mutable_metrics()->mutable_average_duration() =
        EncodeGoogleApiProto(average_duration);
    *traces.add_traces() = trace;
  }
  return traces;
}

Tracer& Tracer::Initialize(bool enable) {
  static absl::NoDestructor<Tracer> tracer(enable);
  return *tracer;
}

Tracer& Tracer::GetInstance() { return Initialize(false); }

void Tracer::EnableTracer(const bool enable) { enabled_ = enable; }

}  // namespace milotic_tlbmc
