#include "frc971/zeroing/pulse_index.h"

#include <cmath>
#include <limits>

#include "glog/logging.h"

namespace frc971::zeroing {

void PulseIndexZeroingEstimator::Reset() {
  max_index_position_ = ::std::numeric_limits<double>::lowest();
  min_index_position_ = ::std::numeric_limits<double>::max();
  offset_ = 0;
  last_used_index_pulse_count_ = 0;
  zeroed_ = false;
  error_ = false;
}

void PulseIndexZeroingEstimator::StoreIndexPulseMaxAndMin(
    const IndexPosition &info) {
  // If we have a new index pulse.
  if (last_used_index_pulse_count_ != info.index_pulses()) {
    // If the latest pulses's position is outside the range we've currently
    // seen, record it appropriately.
    if (info.latched_encoder() > max_index_position_) {
      max_index_position_ = info.latched_encoder();
    }
    if (info.latched_encoder() < min_index_position_) {
      min_index_position_ = info.latched_encoder();
    }
    last_used_index_pulse_count_ = info.index_pulses();
  }
}

int PulseIndexZeroingEstimator::IndexPulseCount() const {
  if (min_index_position_ > max_index_position_) {
    // This condition means we haven't seen a pulse yet.
    return 0;
  }

  // Calculate the number of pulses encountered so far.
  return 1 + static_cast<int>(
                 ::std::round((max_index_position_ - min_index_position_) /
                              constants_.index_difference));
}

void PulseIndexZeroingEstimator::UpdateEstimate(const IndexPosition &info) {
  StoreIndexPulseMaxAndMin(info);
  const int index_pulse_count = IndexPulseCount();
  if (index_pulse_count > constants_.index_pulse_count) {
    if (!error_) {
      VLOG(1) << "Got more index pulses than expected. Got "
              << index_pulse_count << " expected "
              << constants_.index_pulse_count;
      error_ = true;
    }
  }

  // TODO(austin): Detect if the encoder or index pulse is unplugged.
  // TODO(austin): Detect missing counts.

  if (index_pulse_count == constants_.index_pulse_count && !zeroed_) {
    offset_ = constants_.measured_index_position -
              constants_.known_index_pulse * constants_.index_difference -
              min_index_position_;
    zeroed_ = true;
  } else if (zeroed_ && !error_) {
    // Detect whether the index pulse is somewhere other than where we expect
    // it to be. First we compute the position of the most recent index pulse.
    double index_pulse_distance =
        info.latched_encoder() + offset_ - constants_.measured_index_position;
    // Second we compute the position of the index pulse in terms of
    // the index difference. I.e. if this index pulse is two pulses away from
    // the index pulse that we know about then this number should be positive
    // or negative two.
    double relative_distance =
        index_pulse_distance / constants_.index_difference;
    // Now we compute how far away the measured index pulse is from the
    // expected index pulse.
    double error = relative_distance - ::std::round(relative_distance);
    // This lets us check if the index pulse is within an acceptable error
    // margin of where we expected it to be.
    if (::std::abs(error) > constants_.allowable_encoder_error) {
      VLOG(1)
          << "Encoder ticks out of range since last index pulse. known index "
             "pulse: "
          << constants_.measured_index_position << ", expected index pulse: "
          << round(relative_distance) * constants_.index_difference +
                 constants_.measured_index_position
          << ", actual index pulse: " << info.latched_encoder() + offset_
          << ", "
             "allowable error: "
          << constants_.allowable_encoder_error * constants_.index_difference;
      error_ = true;
    }
  }

  position_ = info.encoder() + offset_;
}

flatbuffers::Offset<PulseIndexZeroingEstimator::State>
PulseIndexZeroingEstimator::GetEstimatorState(
    flatbuffers::FlatBufferBuilder *fbb) const {
  State::Builder builder(*fbb);
  builder.add_error(error_);
  builder.add_zeroed(zeroed_);
  builder.add_position(position_);
  builder.add_min_index_position(min_index_position_);
  builder.add_max_index_position(max_index_position_);
  builder.add_index_pulses_seen(IndexPulseCount());
  return builder.Finish();
}

}  // namespace frc971::zeroing
