// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <perftest/results.h>

#include <errno.h>
#include <inttypes.h>
#include <math.h>

#include <fbl/algorithm.h>
#include <zircon/assert.h>

#include <numeric>
#include <utility>

namespace perftest {
namespace {

double Mean(const fbl::Vector<double>& values) {
  double sum = std::accumulate(values.begin(), values.end(), 0.0);
  return sum / static_cast<double>(values.size());
}

double Min(const fbl::Vector<double>& values) {
  return *fbl::min_element(values.begin(), values.end());
}

double Max(const fbl::Vector<double>& values) {
  return *fbl::max_element(values.begin(), values.end());
}

double StdDev(const fbl::Vector<double>& values, double mean) {
  double sum_of_squared_diffs = 0.0;
  for (double value : values) {
    double diff = value - mean;
    sum_of_squared_diffs += diff * diff;
  }
  return sqrt(sum_of_squared_diffs / static_cast<double>(values.size()));
}

// Comparison function for use with qsort().
int CompareDoubles(const void* ptr1, const void* ptr2) {
  double val1 = *reinterpret_cast<const double*>(ptr1);
  double val2 = *reinterpret_cast<const double*>(ptr2);
  if (val1 < val2) {
    return -1;
  }
  if (val1 > val2) {
    return 1;
  }
  return 0;
}

double Median(const fbl::Vector<double>& values) {
  // Make a sorted copy of the vector.
  fbl::Vector<double> copy;
  copy.reserve(values.size());
  for (double value : values) {
    copy.push_back(value);
  }
  qsort(copy.data(), copy.size(), sizeof(copy[0]), CompareDoubles);

  size_t index = copy.size() / 2;
  // Interpolate two values if necessary.
  if (copy.size() % 2 == 0) {
    return (copy[index - 1] + copy[index]) / 2;
  }
  return copy[index];
}

}  // namespace

SummaryStatistics TestCaseResults::GetSummaryStatistics() const {
  ZX_ASSERT(values.size() > 0);
  double mean = Mean(values);
  return SummaryStatistics{
      .min = Min(values),
      .max = Max(values),
      .mean = mean,
      .std_dev = StdDev(values, mean),
      .median = Median(values),
  };
}

void WriteJSONString(FILE* out_file, const char* string) {
  fputc('"', out_file);
  for (const char* ptr = string; *ptr; ptr++) {
    uint8_t c = *ptr;
    if (c == '"') {
      fputs("\\\"", out_file);
    } else if (c == '\\') {
      fputs("\\\\", out_file);
    } else if (c < 32 || c >= 128) {
      // Escape non-printable characters (<32) and top-bit-set
      // characters (>=128).
      //
      // TODO(TO-824): Handle top-bit-set characters better.  Ideally
      // we should treat the input string as UTF-8 and preserve the
      // encoded Unicode in the JSON.  We could interpret the UTF-8
      // sequences and convert them to \uXXXX escape sequences.
      // Alternatively we could pass through UTF-8, but if we do
      // that, we ought to block overlong UTF-8 sequences to prevent
      // closing quotes from being encoded as overlong UTF-8
      // sequences.
      //
      // The current code treats the input string as a byte array
      // rather than UTF-8, which isn't *necessarily* what we want,
      // but will at least result in valid JSON and make the data
      // recoverable.
      fprintf(out_file, "\\u%04x", c);
    } else {
      fputc(c, out_file);
    }
  }
  fputc('"', out_file);
}

void TestCaseResults::WriteJSON(FILE* out_file) const {
  fprintf(out_file, "{\"label\":");
  WriteJSONString(out_file, label.c_str());
  fprintf(out_file, ",\"test_suite\":");
  WriteJSONString(out_file, test_suite.c_str());
  fprintf(out_file, ",\"unit\":");
  WriteJSONString(out_file, unit.c_str());
  if (bytes_processed_per_run) {
    fprintf(out_file, ",\"bytes_processed_per_run\":%" PRIu64, bytes_processed_per_run);
  }
  fprintf(out_file, ",\"values\":[");
  bool first = true;
  for (const auto value : values) {
    if (!first) {
      fprintf(out_file, ",");
    }
    fprintf(out_file, "%f", value);
    first = false;
  }
  fprintf(out_file, "]}");
}

TestCaseResults* ResultsSet::AddTestCase(const fbl::String& test_suite, const fbl::String& label,
                                         const fbl::String& unit) {
  TestCaseResults test_case(test_suite, label, unit);
  results_.push_back(std::move(test_case));
  return &results_[results_.size() - 1];
}

void ResultsSet::WriteJSON(FILE* out_file) const {
  fprintf(out_file, "[");
  bool first = true;
  for (const auto& test_case_results : results_) {
    if (!first) {
      fprintf(out_file, ",\n");
    }
    test_case_results.WriteJSON(out_file);
    first = false;
  }
  fprintf(out_file, "]");
}

bool ResultsSet::WriteJSONFile(const char* output_filename) const {
  FILE* fh = fopen(output_filename, "w");
  if (!fh) {
    fprintf(stderr, "Failed to open output file \"%s\": %s\n", output_filename, strerror(errno));
    return false;
  }
  WriteJSON(fh);
  fclose(fh);
  return true;
}

void ResultsSet::PrintSummaryStatistics(FILE* out_file) const {
  // Print table headings row.
  fprintf(out_file, "%10s %10s %10s %10s %10s %-12s %15s %s\n", "Mean", "Std dev", "Min", "Max",
          "Median", "Unit", "Mean Mbytes/sec", "Test case");
  if (results_.size() == 0) {
    fprintf(out_file, "(No test results)\n");
  }
  for (const auto& test : results_) {
    SummaryStatistics stats = test.GetSummaryStatistics();
    fprintf(out_file, "%10.0f %10.0f %10.0f %10.0f %10.0f %-12s", stats.mean, stats.std_dev,
            stats.min, stats.max, stats.median, test.unit.c_str());
    // Output the throughput column.
    if (test.bytes_processed_per_run != 0 && test.unit == "nanoseconds") {
      double bytes_per_second =
          static_cast<double>(test.bytes_processed_per_run) / stats.mean * 1e9;
      double mbytes_per_second = bytes_per_second / (1024 * 1024);
      fprintf(out_file, " %15.3f", mbytes_per_second);
    } else {
      fprintf(out_file, " %15s", "N/A");
    }
    fprintf(out_file, " %s\n", test.label.c_str());
  }
}

}  // namespace perftest
