// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <string>
#include <vector>

#include "benchmark/export.h"
#include "benchmark/reporter.h"
#include "benchmark_api_internal.h"
#include "check.h"
#include "complexity.h"

// File format reference: http://edoceo.com/utilitas/csv-file-format.

namespace benchmark {

namespace {
const std::vector<const char*> elements = {
    "name",           "iterations",       "real_time",        "cpu_time",
    "time_unit",      "bytes_per_second", "items_per_second", "label",
    "error_occurred", "error_message"};

std::string CsvEscape(const std::string& s) {
  std::string tmp;
  tmp.reserve(s.size() + 2);
  for (char c : s) {
    switch (c) {
      case '"':
        tmp += "\"\"";
        break;
      default:
        tmp += c;
        break;
    }
  }
  return '"' + tmp + '"';
}
}  // namespace

BENCHMARK_EXPORT
bool CSVReporter::ReportContext(const Context& context) {
  PrintBasicContext(&GetErrorStream(), context);
  return true;
}

BENCHMARK_EXPORT
void CSVReporter::ReportRuns(const std::vector<Run>& reports) {
  std::ostream& Out = GetOutputStream();

  if (!printed_header_) {
    // save the names of all the user counters
    for (const auto& run : reports) {
      for (const auto& cnt : run.counters) {
        if (cnt.first == "bytes_per_second" ||
            cnt.first == "items_per_second") {
          continue;
        }
        user_counter_names_.insert(cnt.first);
      }
    }

    // print the header
    for (auto B = elements.begin(); B != elements.end();) {
      Out << *B++;
      if (B != elements.end()) {
        Out << ",";
      }
    }
    for (auto B = user_counter_names_.begin();
         B != user_counter_names_.end();) {
      Out << ",\"" << *B++ << "\"";
    }
    Out << "\n";

    printed_header_ = true;
  } else {
    // check that all the current counters are saved in the name set
    for (const auto& run : reports) {
      for (const auto& cnt : run.counters) {
        if (cnt.first == "bytes_per_second" ||
            cnt.first == "items_per_second") {
          continue;
        }
        BM_CHECK(user_counter_names_.find(cnt.first) !=
                 user_counter_names_.end())
            << "All counters must be present in each run. "
            << "Counter named \"" << cnt.first
            << "\" was not in a run after being added to the header";
      }
    }
  }

  // print results for each run
  for (const auto& run : reports) {
    PrintRunData(run);
  }
}

BENCHMARK_EXPORT
void CSVReporter::PrintRunData(const Run& run) {
  std::ostream& Out = GetOutputStream();
  Out << CsvEscape(run.benchmark_name()) << ",";
  if (run.skipped != 0u) {
    Out << std::string(elements.size() - 3, ',');
    Out << std::boolalpha << (internal::SkippedWithError == run.skipped) << ",";
    Out << CsvEscape(run.skip_message) << "\n";
    return;
  }

  // Do not print iteration on bigO and RMS report
  if (!run.report_big_o && !run.report_rms) {
    Out << run.iterations;
  }
  Out << ",";

  if (run.run_type != Run::RT_Aggregate ||
      run.aggregate_unit == StatisticUnit::kTime) {
    Out << run.GetAdjustedRealTime() << ",";
    Out << run.GetAdjustedCPUTime() << ",";
  } else {
    assert(run.aggregate_unit == StatisticUnit::kPercentage);
    Out << run.real_accumulated_time << ",";
    Out << run.cpu_accumulated_time << ",";
  }

  // Do not print timeLabel on bigO and RMS report
  if (run.report_big_o) {
    Out << GetBigOString(run.complexity);
  } else if (!run.report_rms &&
             run.aggregate_unit != StatisticUnit::kPercentage) {
    Out << GetTimeUnitString(run.time_unit);
  }
  Out << ",";

  if (run.counters.find("bytes_per_second") != run.counters.end()) {
    Out << run.counters.at("bytes_per_second");
  }
  Out << ",";
  if (run.counters.find("items_per_second") != run.counters.end()) {
    Out << run.counters.at("items_per_second");
  }
  Out << ",";
  if (!run.report_label.empty()) {
    Out << CsvEscape(run.report_label);
  }
  Out << ",,";  // for error_occurred and error_message

  // Print user counters
  for (const auto& ucn : user_counter_names_) {
    auto it = run.counters.find(ucn);
    if (it == run.counters.end()) {
      Out << ",";
    } else {
      Out << "," << it->second;
    }
  }
  Out << '\n';
}

BENCHMARK_EXPORT
void CSVReporter::List(
    const std::vector<internal::BenchmarkInstance>& benchmarks) {
  std::ostream& out = GetOutputStream();
  out << "name\n";
  for (const internal::BenchmarkInstance& benchmark : benchmarks) {
    out << CsvEscape(benchmark.name().str()) << "\n";
  }
}

}  // end namespace benchmark
