/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "test/testsupport/perf_test.h"

#include <stdio.h>

#include <algorithm>
#include <fstream>
#include <set>
#include <sstream>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/numerics/samples_stats_counter.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/mutex.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/perf_test_histogram_writer.h"

namespace webrtc {
namespace test {

namespace {

std::string UnitWithDirection(
    absl::string_view units,
    webrtc::test::ImproveDirection improve_direction) {
  switch (improve_direction) {
    case webrtc::test::ImproveDirection::kNone:
      return std::string(units);
    case webrtc::test::ImproveDirection::kSmallerIsBetter:
      return std::string(units) + "_smallerIsBetter";
    case webrtc::test::ImproveDirection::kBiggerIsBetter:
      return std::string(units) + "_biggerIsBetter";
  }
}

std::vector<SamplesStatsCounter::StatsSample> GetSortedSamples(
    const SamplesStatsCounter& counter) {
  rtc::ArrayView<const SamplesStatsCounter::StatsSample> view =
      counter.GetTimedSamples();
  std::vector<SamplesStatsCounter::StatsSample> out(view.begin(), view.end());
  std::stable_sort(out.begin(), out.end(),
                   [](const SamplesStatsCounter::StatsSample& a,
                      const SamplesStatsCounter::StatsSample& b) {
                     return a.time < b.time;
                   });
  return out;
}

template <typename Container>
void OutputListToStream(std::ostream* ostream, const Container& values) {
  const char* sep = "";
  for (const auto& v : values) {
    (*ostream) << sep << v;
    sep = ",";
  }
}

struct PlottableCounter {
  std::string graph_name;
  std::string trace_name;
  webrtc::SamplesStatsCounter counter;
  std::string units;
};

class PlottableCounterPrinter {
 public:
  PlottableCounterPrinter() : output_(stdout) {}

  void SetOutput(FILE* output) {
    MutexLock lock(&mutex_);
    output_ = output;
  }

  void AddCounter(absl::string_view graph_name,
                  absl::string_view trace_name,
                  const webrtc::SamplesStatsCounter& counter,
                  absl::string_view units) {
    MutexLock lock(&mutex_);
    plottable_counters_.push_back({std::string(graph_name),
                                   std::string(trace_name), counter,
                                   std::string(units)});
  }

  void Print(const std::vector<std::string>& desired_graphs_raw) const {
    std::set<std::string> desired_graphs(desired_graphs_raw.begin(),
                                         desired_graphs_raw.end());
    MutexLock lock(&mutex_);
    for (auto& counter : plottable_counters_) {
      if (!desired_graphs.empty()) {
        auto it = desired_graphs.find(counter.graph_name);
        if (it == desired_graphs.end()) {
          continue;
        }
      }

      std::ostringstream value_stream;
      value_stream.precision(8);
      value_stream << R"({"graph_name":")" << counter.graph_name << R"(",)";
      value_stream << R"("trace_name":")" << counter.trace_name << R"(",)";
      value_stream << R"("units":")" << counter.units << R"(",)";
      if (!counter.counter.IsEmpty()) {
        value_stream << R"("mean":)" << counter.counter.GetAverage() << ',';
        value_stream << R"("std":)" << counter.counter.GetStandardDeviation()
                     << ',';
      }
      value_stream << R"("samples":[)";
      const char* sep = "";
      for (const auto& sample : counter.counter.GetTimedSamples()) {
        value_stream << sep << R"({"time":)" << sample.time.us() << ','
                     << R"("value":)" << sample.value << '}';
        sep = ",";
      }
      value_stream << "]}";

      fprintf(output_, "PLOTTABLE_DATA: %s\n", value_stream.str().c_str());
    }
  }

 private:
  mutable Mutex mutex_;
  std::vector<PlottableCounter> plottable_counters_ RTC_GUARDED_BY(&mutex_);
  FILE* output_ RTC_GUARDED_BY(&mutex_);
};

PlottableCounterPrinter& GetPlottableCounterPrinter() {
  static PlottableCounterPrinter* printer_ = new PlottableCounterPrinter();
  return *printer_;
}

class ResultsLinePrinter {
 public:
  ResultsLinePrinter() : output_(stdout) {}

  void SetOutput(FILE* output) {
    MutexLock lock(&mutex_);
    output_ = output;
  }

  void PrintResult(absl::string_view graph_name,
                   absl::string_view trace_name,
                   const double value,
                   absl::string_view units,
                   bool important,
                   ImproveDirection improve_direction) {
    std::ostringstream value_stream;
    value_stream.precision(8);
    value_stream << value;

    PrintResultImpl(graph_name, trace_name, value_stream.str(), std::string(),
                    std::string(), UnitWithDirection(units, improve_direction),
                    important);
  }

  void PrintResultMeanAndError(absl::string_view graph_name,
                               absl::string_view trace_name,
                               const double mean,
                               const double error,
                               absl::string_view units,
                               bool important,
                               ImproveDirection improve_direction) {
    std::ostringstream value_stream;
    value_stream.precision(8);
    value_stream << mean << ',' << error;
    PrintResultImpl(graph_name, trace_name, value_stream.str(), "{", "}",
                    UnitWithDirection(units, improve_direction), important);
  }

  void PrintResultList(absl::string_view graph_name,
                       absl::string_view trace_name,
                       const rtc::ArrayView<const double> values,
                       absl::string_view units,
                       const bool important,
                       webrtc::test::ImproveDirection improve_direction) {
    std::ostringstream value_stream;
    value_stream.precision(8);
    OutputListToStream(&value_stream, values);
    PrintResultImpl(graph_name, trace_name, value_stream.str(), "[", "]", units,
                    important);
  }

 private:
  void PrintResultImpl(absl::string_view graph_name,
                       absl::string_view trace_name,
                       absl::string_view values,
                       absl::string_view prefix,
                       absl::string_view suffix,
                       absl::string_view units,
                       bool important) {
    MutexLock lock(&mutex_);
    StringBuilder message;
    message << (important ? "*" : "") << "RESULT " << graph_name << ": "
            << trace_name << "= " << prefix << values << suffix << " " << units;
    // <*>RESULT <graph_name>: <trace_name>= <value> <units>
    // <*>RESULT <graph_name>: <trace_name>= {<mean>, <std deviation>} <units>
    // <*>RESULT <graph_name>: <trace_name>= [<value>,value,value,...,] <units>
    fprintf(output_, "%s\n", message.str().c_str());
  }

  Mutex mutex_;
  FILE* output_ RTC_GUARDED_BY(&mutex_);
};

ResultsLinePrinter& GetResultsLinePrinter() {
  static ResultsLinePrinter* const printer_ = new ResultsLinePrinter();
  return *printer_;
}

PerfTestResultWriter& GetPerfWriter() {
  static PerfTestResultWriter* writer = CreateHistogramWriter();
  return *writer;
}

}  // namespace

void ClearPerfResults() {
  GetPerfWriter().ClearResults();
}

void SetPerfResultsOutput(FILE* output) {
  GetPlottableCounterPrinter().SetOutput(output);
  GetResultsLinePrinter().SetOutput(output);
}

std::string GetPerfResults() {
  return GetPerfWriter().Serialize();
}

void PrintPlottableResults(const std::vector<std::string>& desired_graphs) {
  GetPlottableCounterPrinter().Print(desired_graphs);
}

bool WritePerfResults(const std::string& output_path) {
  std::string results = GetPerfResults();
  CreateDir(DirName(output_path));
  FILE* output = fopen(output_path.c_str(), "wb");
  if (output == NULL) {
    printf("Failed to write to %s.\n", output_path.c_str());
    return false;
  }
  size_t written =
      fwrite(results.c_str(), sizeof(char), results.size(), output);
  fclose(output);

  if (written != results.size()) {
    long expected = results.size();
    printf("Wrote %zu, tried to write %lu\n", written, expected);
    return false;
  }

  return true;
}

void PrintResult(absl::string_view measurement,
                 absl::string_view modifier,
                 absl::string_view trace,
                 const double value,
                 absl::string_view units,
                 bool important,
                 ImproveDirection improve_direction) {
  StringBuilder graph_name;
  graph_name << measurement << modifier;
  RTC_CHECK(std::isfinite(value))
      << "Expected finite value for graph " << graph_name.str()
      << ", trace name " << trace << ", units " << units << ", got " << value;
  GetPerfWriter().LogResult(graph_name.str(), trace, value, units, important,
                            improve_direction);
  GetResultsLinePrinter().PrintResult(graph_name.str(), trace, value, units,
                                      important, improve_direction);
}

void PrintResult(absl::string_view measurement,
                 absl::string_view modifier,
                 absl::string_view trace,
                 const SamplesStatsCounter& counter,
                 absl::string_view units,
                 const bool important,
                 ImproveDirection improve_direction) {
  StringBuilder graph_name;
  graph_name << measurement << modifier;
  GetPlottableCounterPrinter().AddCounter(graph_name.str(), trace, counter,
                                          units);

  double mean = counter.IsEmpty() ? 0 : counter.GetAverage();
  double error = counter.IsEmpty() ? 0 : counter.GetStandardDeviation();

  std::vector<SamplesStatsCounter::StatsSample> timed_samples =
      GetSortedSamples(counter);
  std::vector<double> samples(timed_samples.size());
  for (size_t i = 0; i < timed_samples.size(); ++i) {
    samples[i] = timed_samples[i].value;
  }
  // If we have an empty counter, default it to 0.
  if (samples.empty()) {
    samples.push_back(0);
  }

  GetPerfWriter().LogResultList(graph_name.str(), trace, samples, units,
                                important, improve_direction);
  GetResultsLinePrinter().PrintResultMeanAndError(graph_name.str(), trace, mean,
                                                  error, units, important,
                                                  improve_direction);
}

void PrintResultMeanAndError(absl::string_view measurement,
                             absl::string_view modifier,
                             absl::string_view trace,
                             const double mean,
                             const double error,
                             absl::string_view units,
                             bool important,
                             ImproveDirection improve_direction) {
  RTC_CHECK(std::isfinite(mean));
  RTC_CHECK(std::isfinite(error));

  StringBuilder graph_name;
  graph_name << measurement << modifier;
  GetPerfWriter().LogResultMeanAndError(graph_name.str(), trace, mean, error,
                                        units, important, improve_direction);
  GetResultsLinePrinter().PrintResultMeanAndError(graph_name.str(), trace, mean,
                                                  error, units, important,
                                                  improve_direction);
}

void PrintResultList(absl::string_view measurement,
                     absl::string_view modifier,
                     absl::string_view trace,
                     const rtc::ArrayView<const double> values,
                     absl::string_view units,
                     bool important,
                     ImproveDirection improve_direction) {
  for (double v : values) {
    RTC_CHECK(std::isfinite(v));
  }

  StringBuilder graph_name;
  graph_name << measurement << modifier;
  GetPerfWriter().LogResultList(graph_name.str(), trace, values, units,
                                important, improve_direction);
  GetResultsLinePrinter().PrintResultList(graph_name.str(), trace, values,
                                          units, important, improve_direction);
}

}  // namespace test
}  // namespace webrtc
