#include "frc971/zeroing/imu_zeroer.h"

namespace frc971::zeroing {

namespace {
bool DiagStatHasFaults(const ADIS16470DiagStat &diag) {
  return diag.clock_error() || diag.memory_failure() || diag.sensor_failure() ||
         diag.standby_mode() || diag.spi_communication_error() ||
         diag.flash_memory_update_error() || diag.data_path_overrun() ||
         diag.checksum_mismatch();
}
bool ReadingHasFaults(const IMUValues &values) {
  if (values.has_previous_reading_diag_stat() &&
      DiagStatHasFaults(*values.previous_reading_diag_stat())) {
    return true;
  }
  if (values.has_self_test_diag_stat() &&
      DiagStatHasFaults(*values.self_test_diag_stat())) {
    return true;
  }
  if (values.checksum_failed()) {
    return true;
  }
  return false;
}
}  // namespace

ImuZeroer::ImuZeroer(FaultBehavior fault_behavior, double gyro_max_variation)
    : fault_behavior_(fault_behavior), gyro_max_variation_(gyro_max_variation) {
  gyro_average_.setZero();
  last_gyro_sample_.setZero();
  last_accel_sample_.setZero();
}

bool ImuZeroer::Zeroed() const {
  return num_zeroes_ > kRequiredZeroPoints && !Faulted();
}

bool ImuZeroer::Faulted() const { return reading_faulted_ || zeroing_faulted_; }

std::optional<Eigen::Vector3d> ImuZeroer::ZeroedGyro() const {
  return Faulted() ? std::nullopt
                   : std::make_optional<Eigen::Vector3d>(last_gyro_sample_ -
                                                         gyro_average_);
}

std::optional<Eigen::Vector3d> ImuZeroer::ZeroedAccel() const {
  return Faulted() ? std::nullopt
                   : std::make_optional<Eigen::Vector3d>(last_accel_sample_);
}

Eigen::Vector3d ImuZeroer::GyroOffset() const { return gyro_average_; }

bool ImuZeroer::GyroZeroReady() const {
  return gyro_averager_.full() &&
         gyro_averager_.GetRange() < gyro_max_variation_ &&
         (last_gyro_sample_.lpNorm<Eigen::Infinity>() <
          kGyroMaxZeroingMagnitude);
}

bool ImuZeroer::AccelZeroReady() const {
  return accel_averager_.full() &&
         accel_averager_.GetRange() < kAccelMaxVariation;
}

void ImuZeroer::InsertAndProcessMeasurement(const IMUValues &values) {
  if (InsertMeasurement(values)) {
    ProcessMeasurements();
  }
}

bool ImuZeroer::InsertMeasurement(const IMUValues &values) {
  if (ReadingHasFaults(values)) {
    reading_faulted_ = true;
    return false;
  }
  if (fault_behavior_ == FaultBehavior::kTemporary) {
    reading_faulted_ = false;
  }
  last_gyro_sample_ << values.gyro_x(), values.gyro_y(), values.gyro_z();
  gyro_averager_.AddData(last_gyro_sample_);
  last_accel_sample_ << values.accelerometer_x(), values.accelerometer_y(),
      values.accelerometer_z();
  accel_averager_.AddData(last_accel_sample_);
  return true;
}

void ImuZeroer::ProcessMeasurements() {
  if (GyroZeroReady() && AccelZeroReady()) {
    ++good_iters_;
    if (good_iters_ > kSamplesToAverage / 40) {
      const Eigen::Vector3d current_gyro_average = gyro_averager_.GetAverage();
      constexpr double kAverageUpdateWeight = 0.05;
      if (num_zeroes_ > 0) {
        gyro_average_ +=
            (current_gyro_average - gyro_average_) * kAverageUpdateWeight;
      } else {
        gyro_average_ = current_gyro_average;
      }
      if (num_zeroes_ > 0) {
        // If we got a new zero and it is substantially different from the
        // original zero, fault.
        if ((current_gyro_average - gyro_average_).norm() >
            kGyroFaultVariation) {
          zeroing_faulted_ = true;
        } else if (fault_behavior_ == FaultBehavior::kTemporary) {
          zeroing_faulted_ = false;
        }
      }
      ++num_zeroes_;
      gyro_averager_.Reset();
    }
  } else {
    good_iters_ = 0;
  }
}

flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState>
ImuZeroer::PopulateStatus(flatbuffers::FlatBufferBuilder *fbb) const {
  control_loops::drivetrain::ImuZeroerState::Builder builder(*fbb);

  builder.add_zeroed(Zeroed());
  builder.add_faulted(Faulted());
  builder.add_number_of_zeroes(num_zeroes_);

  builder.add_gyro_x_average(GyroOffset().x());
  builder.add_gyro_y_average(GyroOffset().y());
  builder.add_gyro_z_average(GyroOffset().z());

  builder.add_accel_x_average(accel_averager_.GetAverage()[0]);
  builder.add_accel_y_average(accel_averager_.GetAverage()[1]);
  builder.add_accel_z_average(accel_averager_.GetAverage()[2]);

  return builder.Finish();
}

}  // namespace frc971::zeroing
