/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include "obs-precomp.h"  // Precompiled headers
//
#include <mrpt/obs/CObservationCANBusJ1939.h>
#include <mrpt/serialization/CArchive.h>

#include <iostream>

using namespace mrpt::obs;
using namespace mrpt::poses;
using namespace std;

// This must be added to any CSerializable class implementation file.
IMPLEMENTS_SERIALIZABLE(CObservationCANBusJ1939, CObservation, mrpt::obs)

uint8_t CObservationCANBusJ1939::serializeGetVersion() const { return 1; }
void CObservationCANBusJ1939::serializeTo(mrpt::serialization::CArchive& out) const
{
  out << m_pgn << m_src_address << m_priority << m_pdu_format;
  out << m_pdu_spec << m_data_length;
  out.WriteAs<uint32_t>(m_data.size());
  if (!m_data.empty()) out.WriteBuffer(&m_data[0], m_data.size());
  out.WriteAs<uint32_t>(m_raw_frame.size());
  if (!m_raw_frame.empty()) out.WriteBuffer(&m_raw_frame[0], m_raw_frame.size());
  out << sensorLabel << timestamp;
}

void CObservationCANBusJ1939::serializeFrom(mrpt::serialization::CArchive& in, uint8_t version)
{
  switch (version)
  {
    case 0:
    case 1:
    {
      uint32_t i, n;

      m_data.clear();
      m_raw_frame.clear();

      in >> m_pgn;
      in >> m_src_address;
      in >> m_priority;
      in >> m_pdu_format;
      in >> m_pdu_spec;
      in >> m_data_length;

      in >> n;
      m_data.resize(n);
      for (i = 0; i < n; ++i) in >> m_data[i];

      in >> n;
      m_raw_frame.resize(n);
      uint8_t aux;
      for (i = 0; i < n; ++i)
      {
        in >> aux;
        m_raw_frame[i] = char(aux);
      }

      in >> sensorLabel;
      in >> timestamp;
    }
    break;
    default:
      MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(version);
  };
}

void CObservationCANBusJ1939::getDescriptionAsText(std::ostream& o) const
{
  CObservation::getDescriptionAsText(o);

  o << "Priority: " << format("0x%02X", m_priority) << " [Dec: " << int(m_priority) << "]" << endl;
  o << "Parameter Group Number (PGN): " << format("0x%04X", m_pgn) << " [Dec: " << int(m_pgn) << "]"
    << endl;
  o << "PDU Format: " << format("0x%02X", m_pdu_format) << " [Dec: " << int(m_pdu_format) << "]"
    << endl;
  o << "PDU Spec: " << format("0x%02X", m_pdu_spec) << " [Dec: " << int(m_pdu_spec) << "]" << endl;
  o << "Source address: " << format("0x%02X", m_src_address) << " [Dec: " << int(m_src_address)
    << "]" << endl;
  o << "Data length: " << format("0x%02X", m_data_length) << " [Dec: " << int(m_data_length) << "]"
    << endl;
  o << "Data: ";
  for (unsigned char k : m_data) o << format("0x%02X", k) << " ";
  o << " [Dec: ";
  for (unsigned char k : m_data) o << int(k) << " ";
  o << "]" << endl;

  o << "Raw frame: ";
  for (char k : m_raw_frame) o << k;
  o << endl;
}
