#include "proto_loader.hpp"
#include "protocol_buffers_definitions/recordings.pb.h"

#include <fstream>
#include <stdexcept>



ProtoLoader::ProtoLoader(char const* f) :
  filePath_(f)
{
  // Verify that the version of the library that we linked against is
  // compatible with the version of the headers we compiled against.
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  std::fstream input(filePath_, std::ios::in | std::ios::binary);
  if (!recording_.ParseFromIstream(&input)) {
    throw std::runtime_error("Failed to parse input file");
  }
}


ProtoLoader::~ProtoLoader()
{
  // Optional:  Delete all global objects allocated by libprotobuf.
  ::google::protobuf::ShutdownProtobufLibrary();
}


std::vector<Magnetic> ProtoLoader::magnetics() const
{
  double t_prev = 0;
  std::vector<Magnetic> magnetics;
  for (int i = 0; i < recording_.magnetics_size(); i++) {
    auto const& s = recording_.magnetics(i);
    double const t = s.t();
    if (t_prev > t) {
      throw std::runtime_error("Magnetics data not sorted by time");
    }
    magnetics.emplace_back(t, s.x(), s.y(), s.z());
    t_prev = t;
  }
  return magnetics;
}


std::vector<Position> ProtoLoader::groundtruth() const
{
  double t_prev = 0;
  std::vector<Position> groundtruth;
  for (int i=0; i < recording_.positions_size(); i++) {
    auto const& s = recording_.positions(i);
    double const t = s.t();
    if ((t - t_prev) < dt_min) {
      throw std::runtime_error("Groundtruth data invalid");
    }
    groundtruth.emplace_back(t, s.x(), s.y());
    t_prev = t;
  }
  return groundtruth;
}
