#include <unistd.h>

#include <chrono>
#include <cinttypes>
#include <cstdio>
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>

#include "frc971/wpilib/ahal/AnalogInput.h"
#include "frc971/wpilib/ahal/Compressor.h"
#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
#include "frc971/wpilib/ahal/DriverStation.h"
#include "frc971/wpilib/ahal/Encoder.h"
#include "frc971/wpilib/ahal/Relay.h"
#include "frc971/wpilib/ahal/Talon.h"
#include "frc971/wpilib/wpilib_robot_base.h"
#undef ERROR

#include "aos/events/shm_event_loop.h"
#include "aos/init.h"
#include "aos/logging/logging.h"
#include "aos/stl_mutex/stl_mutex.h"
#include "aos/time/time.h"
#include "aos/util/log_interval.h"
#include "aos/util/phased_loop.h"
#include "aos/util/wrapping_counter.h"
#include "frc971/control_loops/drivetrain/drivetrain_output_generated.h"
#include "frc971/control_loops/drivetrain/drivetrain_position_generated.h"
#include "frc971/input/robot_state_generated.h"
#include "frc971/shifter_hall_effect.h"
#include "frc971/wpilib/buffered_pcm.h"
#include "frc971/wpilib/buffered_solenoid.h"
#include "frc971/wpilib/dma.h"
#include "frc971/wpilib/dma_edge_counting.h"
#include "frc971/wpilib/drivetrain_writer.h"
#include "frc971/wpilib/encoder_and_potentiometer.h"
#include "frc971/wpilib/gyro_sender.h"
#include "frc971/wpilib/interrupt_edge_counting.h"
#include "frc971/wpilib/joystick_sender.h"
#include "frc971/wpilib/logging_generated.h"
#include "frc971/wpilib/loop_output_handler.h"
#include "frc971/wpilib/pdp_fetcher.h"
#include "frc971/wpilib/sensor_reader.h"
#include "y2014/constants.h"
#include "y2014/control_loops/claw/claw_output_generated.h"
#include "y2014/control_loops/claw/claw_position_generated.h"
#include "y2014/control_loops/shooter/shooter_output_generated.h"
#include "y2014/control_loops/shooter/shooter_position_generated.h"
#include "y2014/queues/auto_mode_generated.h"

namespace claw = ::y2014::control_loops::claw;
namespace shooter = ::y2014::control_loops::shooter;
using std::make_unique;

namespace y2014 {
namespace wpilib {

// TODO(Brian): Fix the interpretation of the result of GetRaw here and in the
// DMA stuff and then removing the * 2.0 in *_translate.
// The low bit is direction.

double drivetrain_translate(int32_t in) {
  return -static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*4x*/) *
         constants::GetValues().drivetrain_encoder_ratio *
         (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI) * 2.0 / 2.0;
}

double drivetrain_velocity_translate(double in) {
  return (1.0 / in) / 256.0 /*cpr*/ *
         constants::GetValues().drivetrain_encoder_ratio *
         (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI) * 2.0 / 2.0;
}

float hall_translate(const constants::DualHallShifterHallEffect &k,
                     float in_low, float in_high) {
  const float low_ratio =
      0.5 * (in_low - static_cast<float>(k.shifter_hall_effect.low_gear_low)) /
      static_cast<float>(k.low_gear_middle -
                         k.shifter_hall_effect.low_gear_low);
  const float high_ratio =
      0.5 + 0.5 * (in_high - static_cast<float>(k.high_gear_middle)) /
                static_cast<float>(k.shifter_hall_effect.high_gear_high -
                                   k.high_gear_middle);

  // Return low when we are below 1/2, and high when we are above 1/2.
  if (low_ratio + high_ratio < 1.0) {
    return low_ratio;
  } else {
    return high_ratio;
  }
}

double claw_translate(int32_t in) {
  return -static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) /
         (18.0 / 48.0 /*encoder gears*/) / (12.0 / 60.0 /*chain reduction*/) *
         (M_PI / 180.0) * 2.0;
}

double shooter_translate(int32_t in) {
  return static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) *
         16 /*sprocket teeth*/ * 0.375 /*chain pitch*/
         * (2.54 / 100.0 /*in to m*/);
}

static const double kMaximumEncoderPulsesPerSecond =
    5600.0 /* free speed RPM */ * 14.0 / 48.0 /* bottom gear reduction */ *
    18.0 / 32.0 /* big belt reduction */ * 18.0 /
    66.0 /* top gear reduction */ * 48.0 / 18.0 /* encoder gears */ /
    60.0 /* seconds / minute */ * 256.0 /* CPR */ * 4.0 /* edges / pulse */;

class SensorReader : public ::frc971::wpilib::SensorReader {
 public:
  SensorReader(::aos::ShmEventLoop *event_loop)
      : ::frc971::wpilib::SensorReader(event_loop),
        auto_mode_sender_(
            event_loop->MakeSender<::y2014::sensors::AutoMode>("/aos")),
        shooter_position_sender_(
            event_loop->MakeSender<shooter::Position>("/shooter")),
        claw_position_sender_(event_loop->MakeSender<claw::Position>("/claw")),
        drivetrain_position_sender_(
            event_loop
                ->MakeSender<::frc971::control_loops::drivetrain::Position>(
                    "/drivetrain")) {
    // Set it to filter out anything shorter than 1/4 of the minimum pulse width
    // we should ever see.
    UpdateMediumEncoderFilterHz(kMaximumEncoderPulsesPerSecond);
    hall_filter_.SetPeriodNanoSeconds(100000);
  }

  ~SensorReader() override {
    top_reader_.Quit();
    bottom_reader_.Quit();
  }

  void set_auto_selector_analog(::std::unique_ptr<::frc::AnalogInput> analog) {
    auto_selector_analog_ = ::std::move(analog);
  }

  void set_high_left_drive_hall(::std::unique_ptr<::frc::AnalogInput> analog) {
    high_left_drive_hall_ = ::std::move(analog);
  }

  void set_low_right_drive_hall(::std::unique_ptr<::frc::AnalogInput> analog) {
    low_right_drive_hall_ = ::std::move(analog);
  }

  void set_high_right_drive_hall(::std::unique_ptr<::frc::AnalogInput> analog) {
    high_right_drive_hall_ = ::std::move(analog);
  }

  void set_low_left_drive_hall(::std::unique_ptr<::frc::AnalogInput> analog) {
    low_left_drive_hall_ = ::std::move(analog);
  }

  void set_top_claw_encoder(::std::unique_ptr<::frc::Encoder> encoder) {
    medium_encoder_filter_.Add(encoder.get());
    top_reader_.set_encoder(::std::move(encoder));
  }

  void set_top_claw_front_hall(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    top_reader_.set_front_hall(::std::move(hall));
  }

  void set_top_claw_calibration_hall(
      ::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    top_reader_.set_calibration_hall(::std::move(hall));
  }

  void set_top_claw_back_hall(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    top_reader_.set_back_hall(::std::move(hall));
  }

  void set_bottom_claw_encoder(::std::unique_ptr<::frc::Encoder> encoder) {
    medium_encoder_filter_.Add(encoder.get());
    bottom_reader_.set_encoder(::std::move(encoder));
  }

  void set_bottom_claw_front_hall(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    bottom_reader_.set_front_hall(::std::move(hall));
  }

  void set_bottom_claw_calibration_hall(
      ::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    bottom_reader_.set_calibration_hall(::std::move(hall));
  }

  void set_bottom_claw_back_hall(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    bottom_reader_.set_back_hall(::std::move(hall));
  }

  void set_shooter_encoder(::std::unique_ptr<::frc::Encoder> encoder) {
    medium_encoder_filter_.Add(encoder.get());
    shooter_encoder_ = ::std::move(encoder);
  }

  void set_shooter_proximal(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    shooter_proximal_ = ::std::move(hall);
  }

  void set_shooter_distal(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    shooter_distal_ = ::std::move(hall);
  }

  void set_shooter_plunger(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    shooter_plunger_ = ::std::move(hall);
    shooter_plunger_reader_ =
        make_unique<::frc971::wpilib::DMADigitalReader>(shooter_plunger_.get());
  }

  void set_shooter_latch(::std::unique_ptr<::frc::DigitalInput> hall) {
    hall_filter_.Add(hall.get());
    shooter_latch_ = ::std::move(hall);
    shooter_latch_reader_ =
        make_unique<::frc971::wpilib::DMADigitalReader>(shooter_latch_.get());
  }

  void Start() override {
    shooter_proximal_counter_ = make_unique<::frc971::wpilib::DMAEdgeCounter>(
        shooter_encoder_.get(), shooter_proximal_.get());
    shooter_distal_counter_ = make_unique<::frc971::wpilib::DMAEdgeCounter>(
        shooter_encoder_.get(), shooter_distal_.get());

    AddToDMA(shooter_proximal_counter_.get());
    AddToDMA(shooter_distal_counter_.get());
    AddToDMA(shooter_plunger_reader_.get());
    AddToDMA(shooter_latch_reader_.get());

    top_reader_.Start();
    bottom_reader_.Start();
  }

  void RunIteration() {
    const auto &values = constants::GetValues();

    {
      auto builder = drivetrain_position_sender_.MakeBuilder();
      frc971::control_loops::drivetrain::Position::Builder position_builder =
          builder.MakeBuilder<frc971::control_loops::drivetrain::Position>();
      position_builder.add_right_encoder(
          drivetrain_translate(drivetrain_right_encoder_->GetRaw()));
      position_builder.add_left_encoder(
          -drivetrain_translate(drivetrain_left_encoder_->GetRaw()));
      position_builder.add_left_speed(
          drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod()));
      position_builder.add_right_speed(drivetrain_velocity_translate(
          drivetrain_right_encoder_->GetPeriod()));

      const double low_left_hall = low_left_drive_hall_->GetVoltage();
      const double high_left_hall = high_left_drive_hall_->GetVoltage();
      position_builder.add_low_left_hall(low_left_hall);
      position_builder.add_high_left_hall(high_left_hall);
      position_builder.add_left_shifter_position(
          hall_translate(values.left_drive, low_left_hall, high_left_hall));

      const double low_right_hall = low_right_drive_hall_->GetVoltage();
      const double high_right_hall = high_right_drive_hall_->GetVoltage();
      position_builder.add_low_right_hall(low_right_hall);
      position_builder.add_high_right_hall(high_right_hall);
      position_builder.add_right_shifter_position(
          hall_translate(values.right_drive, low_right_hall, high_right_hall));

      builder.CheckOk(builder.Send(position_builder.Finish()));
    }

    {
      auto builder = auto_mode_sender_.MakeBuilder();
      y2014::sensors::AutoMode::Builder auto_builder =
          builder.MakeBuilder<y2014::sensors::AutoMode>();
      auto_builder.add_voltage(auto_selector_analog_->GetVoltage());
      builder.CheckOk(builder.Send(auto_builder.Finish()));
    }
  }

  void RunDmaIteration() {
    {
      auto builder = shooter_position_sender_.MakeBuilder();
      ::frc971::PosedgeOnlyCountedHallEffectStructT pusher_proximal;
      CopyShooterPosedgeCounts(shooter_proximal_counter_.get(),
                               &pusher_proximal);
      flatbuffers::Offset<::frc971::PosedgeOnlyCountedHallEffectStruct>
          pusher_proximal_offset =
              ::frc971::PosedgeOnlyCountedHallEffectStruct::Pack(
                  *builder.fbb(), &pusher_proximal);

      ::frc971::PosedgeOnlyCountedHallEffectStructT pusher_distal;
      CopyShooterPosedgeCounts(shooter_distal_counter_.get(), &pusher_distal);
      flatbuffers::Offset<::frc971::PosedgeOnlyCountedHallEffectStruct>
          pusher_distal_offset =
              ::frc971::PosedgeOnlyCountedHallEffectStruct::Pack(
                  *builder.fbb(), &pusher_distal);

      control_loops::shooter::Position::Builder position_builder =
          builder.MakeBuilder<control_loops::shooter::Position>();
      position_builder.add_position(
          shooter_translate(shooter_encoder_->GetRaw()));
      position_builder.add_plunger(!shooter_plunger_reader_->value());
      position_builder.add_latch(!shooter_latch_reader_->value());
      position_builder.add_pusher_distal(pusher_distal_offset);
      position_builder.add_pusher_proximal(pusher_proximal_offset);

      builder.CheckOk(builder.Send(position_builder.Finish()));
    }

    {
      auto builder = claw_position_sender_.MakeBuilder();
      flatbuffers::Offset<control_loops::claw::HalfClawPosition> top_offset =
          top_reader_.ReadPosition(builder.fbb());
      flatbuffers::Offset<control_loops::claw::HalfClawPosition> bottom_offset =
          bottom_reader_.ReadPosition(builder.fbb());

      control_loops::claw::Position::Builder position_builder =
          builder.MakeBuilder<control_loops::claw::Position>();

      position_builder.add_top(top_offset);
      position_builder.add_bottom(bottom_offset);
      builder.CheckOk(builder.Send(position_builder.Finish()));
    }
  }

 private:
  class HalfClawReader {
   public:
    HalfClawReader(bool reversed) : reversed_(reversed) {}

    void set_encoder(::std::unique_ptr<::frc::Encoder> encoder) {
      encoder_ = ::std::move(encoder);
    }

    void set_front_hall(::std::unique_ptr<::frc::DigitalInput> front_hall) {
      front_hall_ = ::std::move(front_hall);
    }

    void set_calibration_hall(
        ::std::unique_ptr<::frc::DigitalInput> calibration_hall) {
      calibration_hall_ = ::std::move(calibration_hall);
    }

    void set_back_hall(::std::unique_ptr<::frc::DigitalInput> back_hall) {
      back_hall_ = ::std::move(back_hall);
    }

    void Start() {
      front_counter_ = make_unique<::frc971::wpilib::EdgeCounter>(
          encoder_.get(), front_hall_.get());
      synchronizer_.Add(front_counter_.get());
      calibration_counter_ = make_unique<::frc971::wpilib::EdgeCounter>(
          encoder_.get(), calibration_hall_.get());
      synchronizer_.Add(calibration_counter_.get());
      back_counter_ = make_unique<::frc971::wpilib::EdgeCounter>(
          encoder_.get(), back_hall_.get());
      synchronizer_.Add(back_counter_.get());
      synchronized_encoder_ =
          make_unique<::frc971::wpilib::InterruptSynchronizedEncoder>(
              encoder_.get());
      synchronizer_.Add(synchronized_encoder_.get());

      synchronizer_.Start();
    }

    void Quit() { synchronizer_.Quit(); }

    flatbuffers::Offset<control_loops::claw::HalfClawPosition> ReadPosition(
        flatbuffers::FlatBufferBuilder *fbb) {
      const double multiplier = reversed_ ? -1.0 : 1.0;

      synchronizer_.RunIteration();

      ::frc971::HallEffectStructT front;
      CopyPosition(front_counter_.get(), &front);
      flatbuffers::Offset<::frc971::HallEffectStruct> front_offset =
          ::frc971::HallEffectStruct::Pack(*fbb, &front);

      ::frc971::HallEffectStructT calibration;
      CopyPosition(calibration_counter_.get(), &calibration);
      flatbuffers::Offset<::frc971::HallEffectStruct> calibration_offset =
          ::frc971::HallEffectStruct::Pack(*fbb, &calibration);

      ::frc971::HallEffectStructT back;
      CopyPosition(back_counter_.get(), &back);
      flatbuffers::Offset<::frc971::HallEffectStruct> back_offset =
          ::frc971::HallEffectStruct::Pack(*fbb, &back);

      control_loops::claw::HalfClawPosition::Builder half_claw_position_builder(
          *fbb);

      half_claw_position_builder.add_front(front_offset);
      half_claw_position_builder.add_calibration(calibration_offset);
      half_claw_position_builder.add_back(back_offset);
      half_claw_position_builder.add_position(
          multiplier * claw_translate(synchronized_encoder_->get()));
      return half_claw_position_builder.Finish();
    }

   private:
    void CopyPosition(const ::frc971::wpilib::EdgeCounter *counter,
                      ::frc971::HallEffectStructT *out) {
      const double multiplier = reversed_ ? -1.0 : 1.0;

      out->current = !counter->polled_value();
      out->posedge_count = counter->negative_interrupt_count();
      out->negedge_count = counter->positive_interrupt_count();
      out->negedge_value =
          multiplier * claw_translate(counter->last_positive_encoder_value());
      out->posedge_value =
          multiplier * claw_translate(counter->last_negative_encoder_value());
    }

    ::frc971::wpilib::InterruptSynchronizer synchronizer_{55};

    ::std::unique_ptr<::frc971::wpilib::EdgeCounter> front_counter_;
    ::std::unique_ptr<::frc971::wpilib::EdgeCounter> calibration_counter_;
    ::std::unique_ptr<::frc971::wpilib::EdgeCounter> back_counter_;
    ::std::unique_ptr<::frc971::wpilib::InterruptSynchronizedEncoder>
        synchronized_encoder_;

    ::std::unique_ptr<::frc::Encoder> encoder_;
    ::std::unique_ptr<::frc::DigitalInput> front_hall_;
    ::std::unique_ptr<::frc::DigitalInput> calibration_hall_;
    ::std::unique_ptr<::frc::DigitalInput> back_hall_;

    const bool reversed_;
  };

  void CopyShooterPosedgeCounts(
      const ::frc971::wpilib::DMAEdgeCounter *counter,
      ::frc971::PosedgeOnlyCountedHallEffectStructT *output) {
    output->current = !counter->polled_value();
    // These are inverted because the hall effects give logical false when
    // there's a magnet in front of them.
    output->posedge_count = counter->negative_count();
    output->negedge_count = counter->positive_count();
    output->posedge_value =
        shooter_translate(counter->last_negative_encoder_value());
  }

  ::aos::Sender<::y2014::sensors::AutoMode> auto_mode_sender_;
  ::aos::Sender<shooter::Position> shooter_position_sender_;
  ::aos::Sender<claw::Position> claw_position_sender_;
  ::aos::Sender<::frc971::control_loops::drivetrain::Position>
      drivetrain_position_sender_;

  ::std::unique_ptr<::frc::AnalogInput> auto_selector_analog_;

  ::std::unique_ptr<::frc::AnalogInput> low_left_drive_hall_;
  ::std::unique_ptr<::frc::AnalogInput> high_left_drive_hall_;
  ::std::unique_ptr<::frc::AnalogInput> low_right_drive_hall_;
  ::std::unique_ptr<::frc::AnalogInput> high_right_drive_hall_;

  HalfClawReader top_reader_{false}, bottom_reader_{true};

  ::std::unique_ptr<::frc::Encoder> shooter_encoder_;
  ::std::unique_ptr<::frc::DigitalInput> shooter_proximal_, shooter_distal_;
  ::std::unique_ptr<::frc::DigitalInput> shooter_plunger_, shooter_latch_;
  ::std::unique_ptr<::frc971::wpilib::DMAEdgeCounter> shooter_proximal_counter_,
      shooter_distal_counter_;
  ::std::unique_ptr<::frc971::wpilib::DMADigitalReader> shooter_plunger_reader_,
      shooter_latch_reader_;

  ::frc::DigitalGlitchFilter hall_filter_;
};

class SolenoidWriter {
 public:
  SolenoidWriter(::aos::ShmEventLoop *event_loop,
                 const ::std::unique_ptr<::frc971::wpilib::BufferedPcm> &pcm)
      : pcm_(pcm),
        shooter_(event_loop->MakeFetcher<shooter::Output>("/shooter")),
        drivetrain_(
            event_loop
                ->MakeFetcher<::frc971::control_loops::drivetrain::Output>(
                    "/drivetrain")),
        pneumatics_to_log_sender_(
            event_loop->MakeSender<::frc971::wpilib::PneumaticsToLog>("/aos")) {
    event_loop->set_name("Solenoids");
    event_loop->SetRuntimeRealtimePriority(27);

    event_loop->AddPhasedLoop([this](int iterations) { Loop(iterations); },
                              ::std::chrono::milliseconds(20),
                              ::std::chrono::milliseconds(1));
  }

  void set_pressure_switch(
      ::std::unique_ptr<::frc::DigitalInput> pressure_switch) {
    pressure_switch_ = ::std::move(pressure_switch);
  }

  void set_compressor_relay(::std::unique_ptr<::frc::Relay> compressor_relay) {
    compressor_relay_ = ::std::move(compressor_relay);
  }

  void set_drivetrain_left(
      ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
    drivetrain_left_ = ::std::move(s);
  }

  void set_drivetrain_right(
      ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
    drivetrain_right_ = ::std::move(s);
  }

  void set_shooter_latch(
      ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
    shooter_latch_ = ::std::move(s);
  }

  void set_shooter_brake(
      ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
    shooter_brake_ = ::std::move(s);
  }

  void Loop(const int iterations) {
    if (iterations != 1) {
      AOS_LOG(DEBUG, "Solenoids skipped %d iterations\n", iterations - 1);
    }

    {
      shooter_.Fetch();
      if (shooter_.get()) {
        shooter_latch_->Set(!shooter_->latch_piston());
        shooter_brake_->Set(!shooter_->brake_piston());
      }
    }

    {
      drivetrain_.Fetch();
      if (drivetrain_.get()) {
        drivetrain_left_->Set(!drivetrain_->left_high());
        drivetrain_right_->Set(!drivetrain_->right_high());
      }
    }

    {
      auto builder = pneumatics_to_log_sender_.MakeBuilder();

      ::frc971::wpilib::PneumaticsToLog::Builder to_log_builder =
          builder.MakeBuilder<frc971::wpilib::PneumaticsToLog>();
      {
        const bool compressor_on = !pressure_switch_->Get();
        to_log_builder.add_compressor_on(compressor_on);
        if (compressor_on) {
          compressor_relay_->Set(::frc::Relay::kForward);
        } else {
          compressor_relay_->Set(::frc::Relay::kOff);
        }
      }

      pcm_->Flush();
      to_log_builder.add_read_solenoids(pcm_->GetAll());
      (void)builder.Send(to_log_builder.Finish());
    }
  }

 private:
  const ::std::unique_ptr<::frc971::wpilib::BufferedPcm> &pcm_;

  ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> drivetrain_left_;
  ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> drivetrain_right_;
  ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> shooter_latch_;
  ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> shooter_brake_;

  ::std::unique_ptr<::frc::DigitalInput> pressure_switch_;
  ::std::unique_ptr<::frc::Relay> compressor_relay_;

  ::aos::Fetcher<shooter::Output> shooter_;
  ::aos::Fetcher<::frc971::control_loops::drivetrain::Output> drivetrain_;

  aos::Sender<::frc971::wpilib::PneumaticsToLog> pneumatics_to_log_sender_;
};

class ShooterWriter
    : public ::frc971::wpilib::LoopOutputHandler<shooter::Output> {
 public:
  ShooterWriter(::aos::EventLoop *event_loop)
      : ::frc971::wpilib::LoopOutputHandler<shooter::Output>(
            event_loop, ".y2014.control_loops.shooter_queue.output") {}

  void set_shooter_talon(::std::unique_ptr<::frc::Talon> t) {
    shooter_talon_ = ::std::move(t);
  }

 private:
  virtual void Write(const shooter::Output &output) override {
    shooter_talon_->SetSpeed(output.voltage() / 12.0);
  }

  virtual void Stop() override {
    AOS_LOG(WARNING, "shooter output too old\n");
    shooter_talon_->SetDisabled();
  }

  ::std::unique_ptr<::frc::Talon> shooter_talon_;
};

class ClawWriter : public ::frc971::wpilib::LoopOutputHandler<claw::Output> {
 public:
  ClawWriter(::aos::EventLoop *event_loop)
      : ::frc971::wpilib::LoopOutputHandler<claw::Output>(
            event_loop, ".y2014.control_loops.claw_queue.output") {}

  void set_top_claw_talon(::std::unique_ptr<::frc::Talon> t) {
    top_claw_talon_ = ::std::move(t);
  }

  void set_bottom_claw_talon(::std::unique_ptr<::frc::Talon> t) {
    bottom_claw_talon_ = ::std::move(t);
  }

  void set_left_tusk_talon(::std::unique_ptr<::frc::Talon> t) {
    left_tusk_talon_ = ::std::move(t);
  }

  void set_right_tusk_talon(::std::unique_ptr<::frc::Talon> t) {
    right_tusk_talon_ = ::std::move(t);
  }

  void set_intake1_talon(::std::unique_ptr<::frc::Talon> t) {
    intake1_talon_ = ::std::move(t);
  }

  void set_intake2_talon(::std::unique_ptr<::frc::Talon> t) {
    intake2_talon_ = ::std::move(t);
  }

 private:
  virtual void Write(const claw::Output &output) override {
    intake1_talon_->SetSpeed(output.intake_voltage() / 12.0);
    intake2_talon_->SetSpeed(output.intake_voltage() / 12.0);
    bottom_claw_talon_->SetSpeed(-output.bottom_claw_voltage() / 12.0);
    top_claw_talon_->SetSpeed(output.top_claw_voltage() / 12.0);
    left_tusk_talon_->SetSpeed(output.tusk_voltage() / 12.0);
    right_tusk_talon_->SetSpeed(-output.tusk_voltage() / 12.0);
  }

  virtual void Stop() override {
    AOS_LOG(WARNING, "claw output too old\n");
    intake1_talon_->SetDisabled();
    intake2_talon_->SetDisabled();
    bottom_claw_talon_->SetDisabled();
    top_claw_talon_->SetDisabled();
    left_tusk_talon_->SetDisabled();
    right_tusk_talon_->SetDisabled();
  }

  ::std::unique_ptr<::frc::Talon> top_claw_talon_;
  ::std::unique_ptr<::frc::Talon> bottom_claw_talon_;
  ::std::unique_ptr<::frc::Talon> left_tusk_talon_;
  ::std::unique_ptr<::frc::Talon> right_tusk_talon_;
  ::std::unique_ptr<::frc::Talon> intake1_talon_;
  ::std::unique_ptr<::frc::Talon> intake2_talon_;
};

class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
 public:
  ::std::unique_ptr<::frc::Encoder> make_encoder(int index) {
    return make_unique<::frc::Encoder>(10 + index * 2, 11 + index * 2, false,
                                       ::frc::Encoder::k4X);
  }

  void Run() override {
    aos::FlatbufferDetachedBuffer<aos::Configuration> config =
        aos::configuration::ReadConfig("aos_config.json");

    // Thread 1.
    ::aos::ShmEventLoop joystick_sender_event_loop(&config.message());
    ::frc971::wpilib::JoystickSender joystick_sender(
        &joystick_sender_event_loop);
    AddLoop(&joystick_sender_event_loop);

    // Thread 2.
    ::aos::ShmEventLoop pdp_fetcher_event_loop(&config.message());
    ::frc971::wpilib::PDPFetcher pdp_fetcher(&pdp_fetcher_event_loop);
    AddLoop(&pdp_fetcher_event_loop);

    // Thread 3.
    ::aos::ShmEventLoop sensor_reader_event_loop(&config.message());
    SensorReader sensor_reader(&sensor_reader_event_loop);

    // Create this first to make sure it ends up in one of the lower-numbered
    // FPGA slots so we can use it with DMA.
    auto shooter_encoder_temp = make_encoder(2);

    sensor_reader.set_auto_selector_analog(make_unique<::frc::AnalogInput>(4));

    sensor_reader.set_drivetrain_left_encoder(make_encoder(0));
    sensor_reader.set_drivetrain_right_encoder(make_encoder(1));
    sensor_reader.set_high_left_drive_hall(make_unique<::frc::AnalogInput>(1));
    sensor_reader.set_low_left_drive_hall(make_unique<::frc::AnalogInput>(0));
    sensor_reader.set_high_right_drive_hall(make_unique<::frc::AnalogInput>(2));
    sensor_reader.set_low_right_drive_hall(make_unique<::frc::AnalogInput>(3));

    sensor_reader.set_top_claw_encoder(make_encoder(3));
    sensor_reader.set_top_claw_front_hall(
        make_unique<::frc::DigitalInput>(4));  // R2
    sensor_reader.set_top_claw_calibration_hall(
        make_unique<::frc::DigitalInput>(3));  // R3
    sensor_reader.set_top_claw_back_hall(
        make_unique<::frc::DigitalInput>(5));  // R1

    sensor_reader.set_bottom_claw_encoder(make_encoder(4));
    sensor_reader.set_bottom_claw_front_hall(
        make_unique<::frc::DigitalInput>(1));  // L2
    sensor_reader.set_bottom_claw_calibration_hall(
        make_unique<::frc::DigitalInput>(0));  // L3
    sensor_reader.set_bottom_claw_back_hall(
        make_unique<::frc::DigitalInput>(2));  // L1

    sensor_reader.set_shooter_encoder(::std::move(shooter_encoder_temp));
    sensor_reader.set_shooter_proximal(
        make_unique<::frc::DigitalInput>(6));  // S1
    sensor_reader.set_shooter_distal(
        make_unique<::frc::DigitalInput>(7));  // S2
    sensor_reader.set_shooter_plunger(
        make_unique<::frc::DigitalInput>(8));                              // S3
    sensor_reader.set_shooter_latch(make_unique<::frc::DigitalInput>(9));  // S4
    AddLoop(&sensor_reader_event_loop);

    // Thread 4.
    ::aos::ShmEventLoop gyro_event_loop(&config.message());
    ::frc971::wpilib::GyroSender gyro_sender(&gyro_event_loop);
    AddLoop(&gyro_event_loop);

    // Thread 5.
    ::aos::ShmEventLoop output_event_loop(&config.message());
    ::frc971::wpilib::DrivetrainWriter drivetrain_writer(&output_event_loop);
    drivetrain_writer.set_left_controller0(make_unique<::frc::Talon>(5), true);
    drivetrain_writer.set_right_controller0(make_unique<::frc::Talon>(2),
                                            false);

    ::y2014::wpilib::ClawWriter claw_writer(&output_event_loop);
    claw_writer.set_top_claw_talon(make_unique<::frc::Talon>(1));
    claw_writer.set_bottom_claw_talon(make_unique<::frc::Talon>(0));
    claw_writer.set_left_tusk_talon(make_unique<::frc::Talon>(4));
    claw_writer.set_right_tusk_talon(make_unique<::frc::Talon>(3));
    claw_writer.set_intake1_talon(make_unique<::frc::Talon>(7));
    claw_writer.set_intake2_talon(make_unique<::frc::Talon>(8));

    ::y2014::wpilib::ShooterWriter shooter_writer(&output_event_loop);
    shooter_writer.set_shooter_talon(make_unique<::frc::Talon>(6));

    AddLoop(&output_event_loop);

    // Thread 6.
    ::aos::ShmEventLoop solenoid_writer_event_loop(&config.message());
    ::std::unique_ptr<::frc971::wpilib::BufferedPcm> pcm(
        new ::frc971::wpilib::BufferedPcm());
    SolenoidWriter solenoid_writer(&solenoid_writer_event_loop, pcm);
    solenoid_writer.set_drivetrain_left(pcm->MakeSolenoid(6));
    solenoid_writer.set_drivetrain_right(pcm->MakeSolenoid(7));
    solenoid_writer.set_shooter_latch(pcm->MakeSolenoid(5));
    solenoid_writer.set_shooter_brake(pcm->MakeSolenoid(4));

    solenoid_writer.set_pressure_switch(make_unique<::frc::DigitalInput>(25));
    solenoid_writer.set_compressor_relay(make_unique<::frc::Relay>(0));
    AddLoop(&solenoid_writer_event_loop);

    RunLoops();
  }
};

}  // namespace wpilib
}  // namespace y2014

AOS_ROBOT_CLASS(::y2014::wpilib::WPILibRobot);
