#ifndef FRC971_ZEROING_ZEROING_H_
#define FRC971_ZEROING_ZEROING_H_

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <vector>

#include "flatbuffers/flatbuffers.h"

#include "frc971/constants.h"
#include "frc971/control_loops/control_loops_generated.h"

// TODO(pschrader): Flag an error if encoder index pulse is not n revolutions
// away from the last one (i.e. got extra counts from noise, etc..)
//
// TODO(pschrader): Flag error if the pot disagrees too much with the encoder
// after being zeroed.
//
// TODO(pschrader): Watch the offset over long periods of time and flag if it
// gets too far away from the initial value.

namespace frc971::zeroing {

template <typename TPosition, typename TZeroingConstants, typename TState>
class ZeroingEstimator {
 public:
  using Position = TPosition;
  using ZeroingConstants = TZeroingConstants;
  using State = TState;
  virtual ~ZeroingEstimator() {}

  // Returns true if the logic considers the corresponding mechanism to be
  // zeroed.
  virtual bool zeroed() const = 0;

  // Returns the estimated position of the corresponding mechanism.
  virtual double offset() const = 0;

  // Returns true if there has been an error.
  virtual bool error() const = 0;

  // Returns true if an offset is ready.
  virtual bool offset_ready() const = 0;

  // Triggers an internal error. This is used for testing the error
  // logic.
  virtual void TriggerError() = 0;

  // Resets the estimator, clearing error and zeroing states.
  virtual void Reset() = 0;

  // Updates the internal logic with new sensor values
  virtual void UpdateEstimate(const Position &) = 0;

  // Returns the state of the estimator
  virtual flatbuffers::Offset<State> GetEstimatorState(
      flatbuffers::FlatBufferBuilder *fbb) const = 0;
};

// Class to encapsulate the logic to decide when we are moving and which samples
// are safe to use.
template <typename Position, typename PositionBuffer>
class MoveDetector {
 public:
  MoveDetector(size_t filter_size) {
    buffered_samples_.reserve(filter_size);
    Reset();
  }

  // Clears all the state.
  void Reset() {
    buffered_samples_.clear();
    buffered_samples_idx_ = 0;
  }

  // Updates the detector with a new sample.  Returns true if we are moving.
  // buffer_size is the number of samples in the moving buffer, and
  // zeroing_threshold is the max amount we can move within the period specified
  // by buffer_size.
  bool Update(const PositionBuffer &position_buffer, size_t buffer_size,
              double zeroing_threshold) {
    bool moving = true;
    Position position(position_buffer);
    if (buffered_samples_.size() < buffer_size) {
      // Not enough samples to start determining if the robot is moving or not,
      // don't use the samples yet.
      buffered_samples_.push_back(position);
    } else {
      // Have enough samples to start determining if the robot is moving or not.
      buffered_samples_[buffered_samples_idx_] = position;
      const auto minmax_value = ::std::minmax_element(
          buffered_samples_.begin(), buffered_samples_.end(),
          [](const Position &left, const Position &right) {
            return left.encoder < right.encoder;
          });
      const double min_value = minmax_value.first->encoder;
      const double max_value = minmax_value.second->encoder;

      if (::std::abs(max_value - min_value) < zeroing_threshold) {
        // Robot isn't moving, use middle sample to determine offsets.
        moving = false;
      }
    }
    buffered_samples_idx_ = (buffered_samples_idx_ + 1) % buffer_size;
    return moving;
  }

  // Returns a safe sample if we aren't moving as reported by Update.
  const Position &GetSample() const {
    // The robot is not moving, use the middle sample to determine offsets.
    // The middle sample makes it so that we don't use the samples from the
    // beginning or end of periods when the robot is moving.
    const int middle_index =
        (buffered_samples_idx_ + (buffered_samples_.size() / 2)) %
        buffered_samples_.size();
    return buffered_samples_[middle_index];
  }

 private:
  // The last buffer_size samples.
  ::std::vector<Position> buffered_samples_;
  // The index to place the next sample in.
  size_t buffered_samples_idx_;
};

// A trivial ZeroingEstimator which just passes the position straight through.
class RelativeEncoderZeroingEstimator
    : public ZeroingEstimator<RelativePosition,
                              constants::RelativeEncoderZeroingConstants,
                              RelativeEncoderEstimatorState> {
 public:
  explicit RelativeEncoderZeroingEstimator(
      const constants::RelativeEncoderZeroingConstants &) {}

  // Update position with new position from encoder
  void UpdateEstimate(const RelativePosition &position) override {
    position_ = position.encoder();
  }

  // We alre always zeroed
  bool zeroed() const override { return true; }

  // Starting position of the joint
  double offset() const override { return 0; }

  // Has an error occured? Note: Only triggered by TriggerError()
  bool error() const override { return error_; }

  // Offset is always ready, since we are always zeroed.
  bool offset_ready() const override { return true; }

  void TriggerError() override { error_ = true; }

  void Reset() override { error_ = false; }

  flatbuffers::Offset<State> GetEstimatorState(
      flatbuffers::FlatBufferBuilder *fbb) const override {
    State::Builder builder(*fbb);
    builder.add_error(error_);
    builder.add_position(position_);
    return builder.Finish();
  }

 private:
  // Position from encoder relative to start
  double position_ = 0;
  bool error_ = false;
};

}  // namespace frc971::zeroing

#endif  // FRC971_ZEROING_ZEROING_H_
