// Copyright 2012 Google Inc. All Rights Reserved.
// Author: martint@google.com (Martin Thuresson)

#include "third_party/open64_libacml_mv/acml_trace.h"

#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <functional>
#include <string>

#include "base/commandlineflags.h"
#include "base/examine_stack.h"
#include "base/googleinit.h"
#include "base/init_google.h"
#include "base/logging.h"
#include "file/base/file.h"
#include "file/base/helpers.h"
#include "testing/base/public/benchmark.h"
#include "testing/base/public/googletest.h"
#include "third_party/absl/strings/cord.h"
#include "third_party/open64_libacml_mv/libacml.h"
#include "util/task/status.h"

template<typename T>
std::unique_ptr<std::vector<T>> InitTrace(
    const char* filename,
    std::function<T(CordReader* reader)> callback) {
  std::unique_ptr<std::vector<T>> trace(new std::vector<T>);
  Cord cord;
  CHECK_OK(file::GetContents(filename, &cord, file::Defaults()));
  CordReader reader(cord);

  while (!reader.done()) {
    trace->push_back(callback(&reader));
  }

  return trace;
}

// Read a trace file with doubles.
std::unique_ptr<std::vector<double>> GetTraceDouble(const char *filename) {
  std::function<double(CordReader* reader)> read_double =
      [](CordReader* reader) {
    double d;
    CHECK_GE(reader->Available(), sizeof(d));
    reader->ReadN(sizeof(d), reinterpret_cast<char*>(&d));
    return d;
  };
  std::unique_ptr<std::vector<double>> trace(InitTrace<double>(filename,
                                                               read_double));
  return trace;
}

// Read a trace file with pairs of doubles.
std::unique_ptr<std::vector<std::pair<double, double>>> GetTraceDoublePair(
    const char *filename) {
  std::function<std::pair<double, double>(CordReader* reader)> read_double =
      [](CordReader* reader) {
    double d[2];
    CHECK_GE(reader->Available(), sizeof(d));
    reader->ReadN(sizeof(d), reinterpret_cast<char*>(&d));
    return std::make_pair(d[0], d[1]);
  };
  std::unique_ptr<std::vector<std::pair<double, double>>> trace(
      InitTrace<std::pair<double, double>>(filename, read_double));
  return trace;
}

// Read a trace file with floats.
std::unique_ptr<std::vector<float>> GetTraceFloat(const char *filename) {
  std::function<float(CordReader* reader)> read_float =
      [](CordReader* reader) {
    float f;
    const int bytes_to_read = min(sizeof(f), reader->Available());
    reader->ReadN(bytes_to_read, reinterpret_cast<char*>(&f));
    return f;
  };
  std::unique_ptr<std::vector<float>> trace(InitTrace<float>(filename,
                                                             read_float));
  return trace;
}
