#include "y2019/jevois/uart.h"

#include <array>

#include "absl/types/span.h"

#include "aos/util/bitpacking.h"
#include "y2019/jevois/jevois_crc.h"
#ifdef __linux__
#include "aos/logging/logging.h"
#else
#define AOS_CHECK(...)
#define AOS_CHECK_GE(...)
#endif

namespace frc971::jevois {

UartToTeensyBuffer UartPackToTeensy(const CameraFrame &message) {
  std::array<char, uart_to_teensy_size()> buffer;
  absl::Span<char> remaining_space(buffer);
  remaining_space[0] = message.targets.size();
  remaining_space = remaining_space.subspan(1);
  for (size_t i = 0; i < 3; ++i) {
    if (i < message.targets.size()) {
      memcpy(remaining_space.data(), &message.targets[i].distance,
             sizeof(float));
      remaining_space = remaining_space.subspan(sizeof(float));
      memcpy(remaining_space.data(), &message.targets[i].height, sizeof(float));
      remaining_space = remaining_space.subspan(sizeof(float));
      memcpy(remaining_space.data(), &message.targets[i].heading,
             sizeof(float));
      remaining_space = remaining_space.subspan(sizeof(float));
      memcpy(remaining_space.data(), &message.targets[i].skew, sizeof(float));
      remaining_space = remaining_space.subspan(sizeof(float));
    } else {
      remaining_space = remaining_space.subspan(sizeof(float) * 4);
    }
  }
  remaining_space[0] = message.age.count();
  remaining_space = remaining_space.subspan(1);
  {
    uint16_t crc = jevois_crc_init();
    crc = jevois_crc_update(crc, buffer.data(),
                            buffer.size() - remaining_space.size());
    crc = jevois_crc_finalize(crc);
    AOS_CHECK_GE(static_cast<size_t>(remaining_space.size()), sizeof(crc));
    memcpy(&remaining_space[0], &crc, sizeof(crc));
    remaining_space = remaining_space.subspan(sizeof(crc));
  }
  AOS_CHECK(remaining_space.empty());
  UartToTeensyBuffer result;
  result.resize(result.capacity());
  result.resize(
      CobsEncode<uart_to_teensy_size()>(buffer, absl::Span<char>(result))
          .size());
  return result;
}

std::optional<CameraFrame> UartUnpackToTeensy(
    absl::Span<const char> encoded_buffer) {
  std::array<char, uart_to_teensy_size()> buffer;
  if (static_cast<size_t>(
          CobsDecode<uart_to_teensy_size()>(encoded_buffer, &buffer).size()) !=
      buffer.size()) {
    return std::nullopt;
  }

  CameraFrame message;
  absl::Span<const char> remaining_input(buffer);
  const int number_targets = remaining_input[0];
  remaining_input = remaining_input.subspan(1);
  for (int i = 0; i < 3; ++i) {
    if (i < number_targets) {
      message.targets.push_back({});
      Target *const target = &message.targets.back();
      memcpy(&target->distance, remaining_input.data(), sizeof(float));
      remaining_input = remaining_input.subspan(sizeof(float));
      memcpy(&target->height, remaining_input.data(), sizeof(float));
      remaining_input = remaining_input.subspan(sizeof(float));
      memcpy(&target->heading, remaining_input.data(), sizeof(float));
      remaining_input = remaining_input.subspan(sizeof(float));
      memcpy(&target->skew, remaining_input.data(), sizeof(float));
      remaining_input = remaining_input.subspan(sizeof(float));
    } else {
      remaining_input = remaining_input.subspan(sizeof(float) * 4);
    }
  }
  message.age = camera_duration(remaining_input[0]);
  remaining_input = remaining_input.subspan(1);
  {
    uint16_t calculated_crc = jevois_crc_init();
    calculated_crc = jevois_crc_update(calculated_crc, buffer.data(),
                                       buffer.size() - remaining_input.size());
    calculated_crc = jevois_crc_finalize(calculated_crc);
    uint16_t received_crc;
    AOS_CHECK_GE(static_cast<size_t>(remaining_input.size()),
                 sizeof(received_crc));
    memcpy(&received_crc, &remaining_input[0], sizeof(received_crc));
    remaining_input = remaining_input.subspan(sizeof(received_crc));
    AOS_CHECK(remaining_input.empty());
    if (calculated_crc != received_crc) {
      return std::nullopt;
    }
  }
  return message;
}

UartToCameraBuffer UartPackToCamera(const CameraCalibration &message) {
  std::array<char, uart_to_camera_size()> buffer;
  absl::Span<char> remaining_space(buffer);
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 4; ++j) {
      memcpy(remaining_space.data(), &message.calibration(i, j), sizeof(float));
      remaining_space = remaining_space.subspan(sizeof(float));
    }
  }
  {
    const int64_t teensy_now = message.teensy_now.time_since_epoch().count();
    memcpy(remaining_space.data(), &teensy_now, sizeof(teensy_now));
    remaining_space = remaining_space.subspan(sizeof(teensy_now));
  }
  {
    const int64_t realtime_now =
        message.realtime_now.time_since_epoch().count();
    memcpy(remaining_space.data(), &realtime_now, sizeof(realtime_now));
    remaining_space = remaining_space.subspan(sizeof(realtime_now));
  }
  memcpy(remaining_space.data(), &message.camera_command, 1);
  remaining_space = remaining_space.subspan(1);
  {
    uint16_t crc = jevois_crc_init();
    crc = jevois_crc_update(crc, buffer.data(),
                            buffer.size() - remaining_space.size());
    crc = jevois_crc_finalize(crc);
    AOS_CHECK_GE(static_cast<size_t>(remaining_space.size()), sizeof(crc));
    memcpy(&remaining_space[0], &crc, sizeof(crc));
    remaining_space = remaining_space.subspan(sizeof(crc));
  }
  AOS_CHECK(remaining_space.empty());
  UartToCameraBuffer result;
  result.resize(result.capacity());
  result.resize(
      CobsEncode<uart_to_camera_size()>(buffer, absl::Span<char>(result))
          .size());
  return result;
}

std::optional<CameraCalibration> UartUnpackToCamera(
    absl::Span<const char> encoded_buffer) {
  std::array<char, uart_to_camera_size()> buffer;
  if (static_cast<size_t>(
          CobsDecode<uart_to_camera_size()>(encoded_buffer, &buffer).size()) !=
      buffer.size()) {
    return std::nullopt;
  }

  CameraCalibration message;
  absl::Span<const char> remaining_input(buffer);
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 4; ++j) {
      memcpy(&message.calibration(i, j), remaining_input.data(), sizeof(float));
      remaining_input = remaining_input.subspan(sizeof(float));
    }
  }
  {
    int64_t teensy_now;
    memcpy(&teensy_now, remaining_input.data(), sizeof(teensy_now));
    message.teensy_now = aos::monotonic_clock::time_point(
        aos::monotonic_clock::duration(teensy_now));
    remaining_input = remaining_input.subspan(sizeof(teensy_now));
  }
  {
    int64_t realtime_now;
    memcpy(&realtime_now, remaining_input.data(), sizeof(realtime_now));
    message.realtime_now = aos::realtime_clock::time_point(
        aos::realtime_clock::duration(realtime_now));
    remaining_input = remaining_input.subspan(sizeof(realtime_now));
  }
  memcpy(&message.camera_command, remaining_input.data(), 1);
  remaining_input = remaining_input.subspan(1);
  {
    uint16_t calculated_crc = jevois_crc_init();
    calculated_crc = jevois_crc_update(calculated_crc, buffer.data(),
                                       buffer.size() - remaining_input.size());
    calculated_crc = jevois_crc_finalize(calculated_crc);
    uint16_t received_crc;
    AOS_CHECK_GE(static_cast<size_t>(remaining_input.size()),
                 sizeof(received_crc));
    memcpy(&received_crc, &remaining_input[0], sizeof(received_crc));
    remaining_input = remaining_input.subspan(sizeof(received_crc));
    AOS_CHECK(remaining_input.empty());
    if (calculated_crc != received_crc) {
      return std::nullopt;
    }
  }
  return message;
}

}  // namespace frc971::jevois
