// 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 <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <tuple>
#include <vector>

#include "benchmark/benchmark.h"
#include "check.h"
#include "string_util.h"
#include "timers.h"

namespace benchmark {

BenchmarkReporter::BenchmarkReporter()
    : output_stream_(&std::cout), error_stream_(&std::cerr) {}

BenchmarkReporter::~BenchmarkReporter() {}

void BenchmarkReporter::PrintBasicContext(std::ostream *out,
                                          Context const &context) {
  BM_CHECK(out) << "cannot be null";
  auto &Out = *out;

#ifndef BENCHMARK_OS_QURT
  // Date/time information is not available on QuRT.
  // Attempting to get it via this call cause the binary to crash.
  Out << LocalDateTimeString() << "\n";
#endif

  if (benchmark::BenchmarkReporter::Context::executable_name != nullptr) {
    Out << "Running " << benchmark::BenchmarkReporter::Context::executable_name
        << "\n";
  }

  const CPUInfo &info = context.cpu_info;
  Out << "Run on (" << info.num_cpus << " X "
      << (info.cycles_per_second / 1000000.0) << " MHz CPU "
      << ((info.num_cpus > 1) ? "s" : "") << ")\n";
  if (!info.caches.empty()) {
    Out << "CPU Caches:\n";
    for (const auto &CInfo : info.caches) {
      Out << "  L" << CInfo.level << " " << CInfo.type << " "
          << (CInfo.size / 1024) << " KiB";
      if (CInfo.num_sharing != 0) {
        Out << " (x" << (info.num_cpus / CInfo.num_sharing) << ")";
      }
      Out << "\n";
    }
  }
  if (!info.load_avg.empty()) {
    Out << "Load Average: ";
    for (auto It = info.load_avg.begin(); It != info.load_avg.end();) {
      Out << StrFormat("%.2f", *It++);
      if (It != info.load_avg.end()) {
        Out << ", ";
      }
    }
    Out << "\n";
  }

  std::map<std::string, std::string> *global_context =
      internal::GetGlobalContext();

  if (global_context != nullptr) {
    for (const auto &kv : *global_context) {
      Out << kv.first << ": " << kv.second << "\n";
    }
  }

  if (CPUInfo::Scaling::ENABLED == info.scaling) {
    Out << "***WARNING*** CPU scaling is enabled, the benchmark "
           "real time measurements may be noisy and will incur extra "
           "overhead.\n";
  }

  const SystemInfo &sysinfo = context.sys_info;
  if (SystemInfo::ASLR::ENABLED == sysinfo.ASLRStatus) {
    Out << "***WARNING*** ASLR is enabled, the results may have unreproducible "
           "noise in them.\n";
  }

#ifndef NDEBUG
  Out << "***WARNING*** Library was built as DEBUG. Timings may be "
         "affected.\n";
#endif
}

// No initializer because it's already initialized to NULL.
const char *BenchmarkReporter::Context::executable_name;

BenchmarkReporter::Context::Context()
    : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {}

std::string BenchmarkReporter::Run::benchmark_name() const {
  std::string name = run_name.str();
  if (run_type == RT_Aggregate) {
    name += "_" + aggregate_name;
  }
  return name;
}

double BenchmarkReporter::Run::GetAdjustedRealTime() const {
  double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit);
  if (iterations != 0) {
    new_time /= static_cast<double>(iterations);
  }
  return new_time;
}

double BenchmarkReporter::Run::GetAdjustedCPUTime() const {
  double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit);
  if (iterations != 0) {
    new_time /= static_cast<double>(iterations);
  }
  return new_time;
}

}  // end namespace benchmark
