#include <unistd.h>

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

#include "frc971/wpilib/ahal/AnalogInput.h"
#include "frc971/wpilib/ahal/Counter.h"
#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
#include "frc971/wpilib/ahal/DriverStation.h"
#include "frc971/wpilib/ahal/Encoder.h"
#include "frc971/wpilib/ahal/TalonFX.h"
#include "frc971/wpilib/ahal/VictorSP.h"
#undef ERROR

#include "ctre/phoenix6/TalonFX.hpp"
#include "gflags/gflags.h"

#include "aos/commonmath.h"
#include "aos/events/event_loop.h"
#include "aos/events/shm_event_loop.h"
#include "aos/init.h"
#include "aos/logging/logging.h"
#include "aos/network/team_number.h"
#include "aos/realtime.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/autonomous/auto_mode_generated.h"
#include "frc971/control_loops/drivetrain/drivetrain_position_generated.h"
#include "frc971/input/robot_state_generated.h"
#include "frc971/wpilib/ADIS16448.h"
#include "frc971/wpilib/ADIS16470.h"
#include "frc971/wpilib/buffered_pcm.h"
#include "frc971/wpilib/buffered_solenoid.h"
#include "frc971/wpilib/dma.h"
#include "frc971/wpilib/drivetrain_writer.h"
#include "frc971/wpilib/encoder_and_potentiometer.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 "frc971/wpilib/wpilib_robot_base.h"
#include "y2020/constants.h"
#include "y2020/control_loops/superstructure/shooter/shooter_tuning_readings_generated.h"
#include "y2020/control_loops/superstructure/superstructure_output_generated.h"
#include "y2020/control_loops/superstructure/superstructure_position_generated.h"

DEFINE_bool(shooter_tuning, true,
            "If true, reads from ball beambreak sensors and sends shooter "
            "tuning readings");

using ::aos::monotonic_clock;
using ::y2020::constants::Values;
namespace superstructure = ::y2020::control_loops::superstructure;
namespace chrono = ::std::chrono;
using std::make_unique;

namespace y2020 {
namespace wpilib {
namespace {

constexpr double kMaxBringupPower = 12.0;

// 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) /
           Values::kDrivetrainEncoderCountsPerRevolution()) *
          (2.0 * M_PI)) *
         Values::kDrivetrainEncoderRatio() *
         control_loops::drivetrain::kWheelRadius;
}

double drivetrain_velocity_translate(double in) {
  return (((1.0 / in) / Values::kDrivetrainCyclesPerRevolution()) *
          (2.0 * M_PI)) *
         Values::kDrivetrainEncoderRatio() *
         control_loops::drivetrain::kWheelRadius;
}

double turret_pot_translate(double voltage) {
  return voltage * Values::kTurretPotRatio() *
         (10.0 /*turns*/ / 5.0 /*volts*/) * (2 * M_PI /*radians*/);
}

constexpr double kMaxFastEncoderPulsesPerSecond =
    std::max({Values::kMaxControlPanelEncoderPulsesPerSecond(),
              Values::kMaxFinisherEncoderPulsesPerSecond(),
              Values::kMaxAcceleratorEncoderPulsesPerSecond()});
static_assert(kMaxFastEncoderPulsesPerSecond <= 1000000.0,
              "fast encoders are too fast");
constexpr double kMaxMediumEncoderPulsesPerSecond =
    std::max({Values::kMaxDrivetrainEncoderPulsesPerSecond(),
              Values::kMaxHoodEncoderPulsesPerSecond(),
              Values::kMaxIntakeEncoderPulsesPerSecond(),
              Values::kMaxTurretEncoderPulsesPerSecond()});

static_assert(kMaxMediumEncoderPulsesPerSecond <= 400000.0,
              "medium encoders are too fast");

void PrintConfigs(ctre::phoenix6::hardware::TalonFX *talon) {
  ctre::phoenix6::configs::TalonFXConfiguration configuration;
  ctre::phoenix::StatusCode status =
      talon->GetConfigurator().Refresh(configuration);
  if (!status.IsOK()) {
    AOS_LOG(ERROR, "Failed to get falcon configuration: %s: %s",
            status.GetName(), status.GetDescription());
  }
  AOS_LOG(INFO, "configuration: %s", configuration.ToString().c_str());
}

void WriteConfigs(ctre::phoenix6::hardware::TalonFX *talon,
                  double stator_current_limit, double supply_current_limit) {
  ctre::phoenix6::configs::CurrentLimitsConfigs current_limits;
  current_limits.StatorCurrentLimit = stator_current_limit;
  current_limits.StatorCurrentLimitEnable = true;
  current_limits.SupplyCurrentLimit = supply_current_limit;
  current_limits.SupplyCurrentLimitEnable = true;

  ctre::phoenix6::configs::TalonFXConfiguration configuration;
  configuration.CurrentLimits = current_limits;

  ctre::phoenix::StatusCode status =
      talon->GetConfigurator().Apply(configuration);
  if (!status.IsOK()) {
    AOS_LOG(ERROR, "Failed to set falcon configuration: %s: %s",
            status.GetName(), status.GetDescription());
  }

  PrintConfigs(talon);
}

void Disable(ctre::phoenix6::hardware::TalonFX *talon) {
  ctre::phoenix6::controls::DutyCycleOut stop_command(0.0);
  stop_command.UpdateFreqHz = 0_Hz;
  stop_command.EnableFOC = true;

  talon->SetControl(stop_command);
}

}  // namespace

// Class to send position messages with sensor readings to our loops.
class SensorReader : public ::frc971::wpilib::SensorReader {
 public:
  SensorReader(::aos::ShmEventLoop *event_loop)
      : ::frc971::wpilib::SensorReader(event_loop),
        auto_mode_sender_(
            event_loop->MakeSender<::frc971::autonomous::AutonomousMode>(
                "/autonomous")),
        superstructure_position_sender_(
            event_loop->MakeSender<superstructure::Position>(
                "/superstructure")),
        drivetrain_position_sender_(
            event_loop
                ->MakeSender<::frc971::control_loops::drivetrain::Position>(
                    "/drivetrain")),
        shooter_tuning_readings_sender_(
            event_loop->MakeSender<superstructure::shooter::TuningReadings>(
                "/superstructure")) {
    // Set to filter out anything shorter than 1/4 of the minimum pulse width
    // we should ever see.
    UpdateFastEncoderFilterHz(kMaxFastEncoderPulsesPerSecond);
    UpdateMediumEncoderFilterHz(kMaxMediumEncoderPulsesPerSecond);

    constants::InitValues();
  }

  // Hood
  void set_hood_encoder(::std::unique_ptr<frc::Encoder> encoder) {
    medium_encoder_filter_.Add(encoder.get());
    hood_encoder_.set_encoder(::std::move(encoder));
  }

  void set_hood_absolute_pwm(
      ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
    hood_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
  }

  void set_hood_single_turn_absolute_pwm(
      ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
    hood_encoder_.set_single_turn_absolute_pwm(::std::move(absolute_pwm));
  }

  // Intake

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

  void set_intake_absolute_pwm(
      ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
    intake_joint_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
  }

  // Turret

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

  void set_turret_absolute_pwm(
      ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
    turret_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
  }

  void set_turret_potentiometer(
      ::std::unique_ptr<frc::AnalogInput> potentiometer) {
    turret_encoder_.set_potentiometer(::std::move(potentiometer));
  }

  // Shooter
  void set_finisher_encoder(::std::unique_ptr<frc::Encoder> encoder) {
    fast_encoder_filter_.Add(encoder.get());
    finisher_encoder_ = ::std::move(encoder);
  }
  void set_left_accelerator_encoder(::std::unique_ptr<frc::Encoder> encoder) {
    fast_encoder_filter_.Add(encoder.get());
    left_accelerator_encoder_ = ::std::move(encoder);
  }

  void set_right_accelerator_encoder(::std::unique_ptr<frc::Encoder> encoder) {
    fast_encoder_filter_.Add(encoder.get());
    right_accelerator_encoder_ = ::std::move(encoder);
  }

  // Auto mode switches.
  void set_autonomous_mode(int i, ::std::unique_ptr<frc::DigitalInput> sensor) {
    medium_encoder_filter_.Add(sensor.get());
    autonomous_modes_.at(i) = ::std::move(sensor);
  }

  void set_imu(frc971::wpilib::ADIS16470 *imu) { imu_ = imu; }

  void set_ball_beambreak_inputs(::std::unique_ptr<frc::DigitalInput> sensor1,
                                 ::std::unique_ptr<frc::DigitalInput> sensor2) {
    ball_beambreak_inputs_[0] = ::std::move(sensor1);
    ball_beambreak_inputs_[1] = ::std::move(sensor2);
    ball_beambreak_reader_.set_input_one(ball_beambreak_inputs_[0].get());
    ball_beambreak_reader_.set_input_two(ball_beambreak_inputs_[1].get());
  }

  void set_ball_intake_beambreak(::std::unique_ptr<frc::DigitalInput> sensor) {
    ball_intake_beambreak_ = ::std::move(sensor);
  }

  void Start() override {
    if (FLAGS_shooter_tuning) {
      AddToDMA(&ball_beambreak_reader_);
    }
  }

  void RunIteration() override {
    if (imu_ != nullptr) {
      imu_->DoReads();
    }

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

      drivetrain_builder.add_right_encoder(
          -drivetrain_translate(drivetrain_right_encoder_->GetRaw()));
      drivetrain_builder.add_right_speed(-drivetrain_velocity_translate(
          drivetrain_right_encoder_->GetPeriod()));

      builder.CheckOk(builder.Send(drivetrain_builder.Finish()));
    }
    const constants::Values &values = constants::GetValues();

    {
      auto builder = superstructure_position_sender_.MakeBuilder();

      // TODO(alex): check new absolute encoder api.
      // Hood
      frc971::AbsoluteAndAbsolutePositionT hood;
      CopyPosition(hood_encoder_, &hood,
                   Values::kHoodEncoderCountsPerRevolution(),
                   Values::kHoodEncoderRatio(),
                   Values::kHoodSingleTurnEncoderRatio(), false);
      flatbuffers::Offset<frc971::AbsoluteAndAbsolutePosition> hood_offset =
          frc971::AbsoluteAndAbsolutePosition::Pack(*builder.fbb(), &hood);

      // Intake
      frc971::AbsolutePositionT intake_joint;
      CopyPosition(intake_joint_encoder_, &intake_joint,
                   Values::kIntakeEncoderCountsPerRevolution(),
                   Values::kIntakeEncoderRatio(), false);
      flatbuffers::Offset<frc971::AbsolutePosition> intake_joint_offset =
          frc971::AbsolutePosition::Pack(*builder.fbb(), &intake_joint);

      // Turret
      frc971::PotAndAbsolutePositionT turret;
      CopyPosition(turret_encoder_, &turret,
                   Values::kTurretEncoderCountsPerRevolution(),
                   Values::kTurretEncoderRatio(), turret_pot_translate, true,
                   values.turret.potentiometer_offset);
      flatbuffers::Offset<frc971::PotAndAbsolutePosition> turret_offset =
          frc971::PotAndAbsolutePosition::Pack(*builder.fbb(), &turret);

      // Shooter
      y2020::control_loops::superstructure::ShooterPositionT shooter;
      shooter.theta_finisher =
          encoder_translate(-finisher_encoder_->GetRaw(),
                            Values::kFinisherEncoderCountsPerRevolution(),
                            Values::kFinisherEncoderRatio());

      shooter.theta_accelerator_left =
          encoder_translate(-left_accelerator_encoder_->GetRaw(),
                            Values::kAcceleratorEncoderCountsPerRevolution(),
                            Values::kAcceleratorEncoderRatio());
      shooter.theta_accelerator_right =
          encoder_translate(right_accelerator_encoder_->GetRaw(),
                            Values::kAcceleratorEncoderCountsPerRevolution(),
                            Values::kAcceleratorEncoderRatio());
      flatbuffers::Offset<y2020::control_loops::superstructure::ShooterPosition>
          shooter_offset =
              y2020::control_loops::superstructure::ShooterPosition::Pack(
                  *builder.fbb(), &shooter);

      superstructure::Position::Builder position_builder =
          builder.MakeBuilder<superstructure::Position>();
      position_builder.add_hood(hood_offset);
      position_builder.add_intake_joint(intake_joint_offset);
      position_builder.add_turret(turret_offset);
      position_builder.add_shooter(shooter_offset);
      position_builder.add_intake_beambreak_triggered(
          ball_intake_beambreak_->Get());

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

    {
      auto builder = auto_mode_sender_.MakeBuilder();

      uint32_t mode = 0;
      for (size_t i = 0; i < autonomous_modes_.size(); ++i) {
        if (autonomous_modes_[i] && autonomous_modes_[i]->Get()) {
          mode |= 1 << i;
        }
      }

      auto auto_mode_builder =
          builder.MakeBuilder<frc971::autonomous::AutonomousMode>();

      auto_mode_builder.add_mode(mode);

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

    if (FLAGS_shooter_tuning) {
      // Distance between beambreak sensors, in meters.
      constexpr double kDistanceBetweenBeambreaks = 0.4813;

      if (ball_beambreak_reader_.pulses_detected() > balls_detected_) {
        balls_detected_ = ball_beambreak_reader_.pulses_detected();

        auto builder = shooter_tuning_readings_sender_.MakeBuilder();
        auto shooter_tuning_readings_builder =
            builder.MakeBuilder<superstructure::shooter::TuningReadings>();
        shooter_tuning_readings_builder.add_velocity_ball(
            kDistanceBetweenBeambreaks / ball_beambreak_reader_.last_width());
        builder.CheckOk(builder.Send(shooter_tuning_readings_builder.Finish()));
      }
    }
  }

 private:
  ::aos::Sender<::frc971::autonomous::AutonomousMode> auto_mode_sender_;
  ::aos::Sender<superstructure::Position> superstructure_position_sender_;
  ::aos::Sender<::frc971::control_loops::drivetrain::Position>
      drivetrain_position_sender_;
  ::aos::Sender<superstructure::shooter::TuningReadings>
      shooter_tuning_readings_sender_;

  ::frc971::wpilib::AbsoluteEncoderAndPotentiometer turret_encoder_;

  ::frc971::wpilib::AbsoluteAndAbsoluteEncoder hood_encoder_;

  ::frc971::wpilib::AbsoluteEncoder intake_joint_encoder_;

  ::std::unique_ptr<::frc::Encoder> finisher_encoder_,
      left_accelerator_encoder_, right_accelerator_encoder_;

  ::std::array<::std::unique_ptr<frc::DigitalInput>, 2> autonomous_modes_;

  frc971::wpilib::ADIS16470 *imu_ = nullptr;

  std::unique_ptr<frc::DigitalInput> ball_intake_beambreak_;

  // Used to interface with the two beam break sensors that the ball for tuning
  // shooter parameters has to pass through.
  // We will time how long it takes to pass between the two sensors to get its
  // velocity.
  std::array<std::unique_ptr<frc::DigitalInput>, 2> ball_beambreak_inputs_;
  frc971::wpilib::DMAPulseSeparationReader ball_beambreak_reader_;
  int balls_detected_ = 0;
};

class SuperstructureWriter
    : public ::frc971::wpilib::LoopOutputHandler<superstructure::Output> {
 public:
  SuperstructureWriter(::aos::EventLoop *event_loop)
      : ::frc971::wpilib::LoopOutputHandler<superstructure::Output>(
            event_loop, "/superstructure") {}

  void set_hood_victor(::std::unique_ptr<::frc::VictorSP> t) {
    hood_victor_ = ::std::move(t);
  }

  void set_intake_joint_victor(::std::unique_ptr<::frc::VictorSP> t) {
    intake_joint_victor_ = ::std::move(t);
  }

  void set_intake_roller_falcon(
      ::std::unique_ptr<::ctre::phoenix6::hardware::TalonFX> t) {
    intake_roller_falcon_ = ::std::move(t);

    WriteConfigs(intake_roller_falcon_.get(),
                 Values::kIntakeRollerStatorCurrentLimit(),
                 Values::kIntakeRollerSupplyCurrentLimit());
  }

  void set_turret_victor(::std::unique_ptr<::frc::VictorSP> t) {
    turret_victor_ = ::std::move(t);
  }

  void set_feeder_falcon(
      ::std::unique_ptr<::ctre::phoenix6::hardware::TalonFX> t) {
    feeder_falcon_ = ::std::move(t);

    WriteConfigs(feeder_falcon_.get(), Values::kFeederStatorCurrentLimit(),
                 Values::kFeederSupplyCurrentLimit());
  }

  void set_washing_machine_control_panel_victor(
      ::std::unique_ptr<::frc::VictorSP> t) {
    washing_machine_control_panel_victor_ = ::std::move(t);
  }

  void set_accelerator_left_falcon(::std::unique_ptr<::frc::TalonFX> t) {
    accelerator_left_falcon_ = ::std::move(t);
  }

  void set_accelerator_right_falcon(::std::unique_ptr<::frc::TalonFX> t) {
    accelerator_right_falcon_ = ::std::move(t);
  }

  void set_finisher_falcon0(::std::unique_ptr<::frc::TalonFX> t) {
    finisher_falcon0_ = ::std::move(t);
  }

  void set_finisher_falcon1(::std::unique_ptr<::frc::TalonFX> t) {
    finisher_falcon1_ = ::std::move(t);
  }

  void set_climber_falcon(
      ::std::unique_ptr<::ctre::phoenix6::hardware::TalonFX> t) {
    climber_falcon_ = ::std::move(t);
    ctre::phoenix6::configs::CurrentLimitsConfigs current_limits;
    current_limits.SupplyCurrentLimit = Values::kClimberSupplyCurrentLimit();
    current_limits.SupplyCurrentLimitEnable = true;

    ctre::phoenix6::configs::TalonFXConfiguration configuration;
    configuration.CurrentLimits = current_limits;

    ctre::phoenix::StatusCode status =
        climber_falcon_->GetConfigurator().Apply(configuration);
    if (!status.IsOK()) {
      AOS_LOG(ERROR, "Failed to set falcon configuration: %s: %s",
              status.GetName(), status.GetDescription());
    }

    PrintConfigs(climber_falcon_.get());
  }

 private:
  void Write(const superstructure::Output &output) override {
    hood_victor_->SetSpeed(std::clamp(-output.hood_voltage(), -kMaxBringupPower,
                                      kMaxBringupPower) /
                           12.0);

    intake_joint_victor_->SetSpeed(std::clamp(-output.intake_joint_voltage(),
                                              -kMaxBringupPower,
                                              kMaxBringupPower) /
                                   12.0);

    WriteCan(-output.intake_roller_voltage(), intake_roller_falcon_.get());

    turret_victor_->SetSpeed(std::clamp(output.turret_voltage(),
                                        -kMaxBringupPower, kMaxBringupPower) /
                             12.0);
    WriteCan(output.feeder_voltage(), feeder_falcon_.get());
    if (washing_machine_control_panel_victor_) {
      washing_machine_control_panel_victor_->SetSpeed(
          std::clamp(-output.washing_machine_spinner_voltage(),
                     -kMaxBringupPower, kMaxBringupPower) /
          12.0);
    }

    accelerator_left_falcon_->SetSpeed(
        std::clamp(-output.accelerator_left_voltage(), -kMaxBringupPower,
                   kMaxBringupPower) /
        12.0);

    accelerator_right_falcon_->SetSpeed(
        std::clamp(output.accelerator_right_voltage(), -kMaxBringupPower,
                   kMaxBringupPower) /
        12.0);

    finisher_falcon1_->SetSpeed(std::clamp(output.finisher_voltage(),
                                           -kMaxBringupPower,
                                           kMaxBringupPower) /
                                12.0);
    finisher_falcon0_->SetSpeed(std::clamp(-output.finisher_voltage(),
                                           -kMaxBringupPower,
                                           kMaxBringupPower) /
                                12.0);

    if (climber_falcon_) {
      WriteCan(output.climber_voltage(), climber_falcon_.get());
    }
  }

  static void WriteCan(const double voltage,
                       ::ctre::phoenix6::hardware::TalonFX *falcon) {
    ctre::phoenix6::controls::DutyCycleOut control(
        std::clamp(voltage, -kMaxBringupPower, kMaxBringupPower) / 12.0);
    control.UpdateFreqHz = 0_Hz;
    control.EnableFOC = true;

    falcon->SetControl(control);
  }

  void Stop() override {
    AOS_LOG(WARNING, "Superstructure output too old.\n");
    hood_victor_->SetDisabled();
    intake_joint_victor_->SetDisabled();
    turret_victor_->SetDisabled();
    if (washing_machine_control_panel_victor_) {
      washing_machine_control_panel_victor_->SetDisabled();
    }
    accelerator_left_falcon_->SetDisabled();
    accelerator_right_falcon_->SetDisabled();
    finisher_falcon0_->SetDisabled();
    finisher_falcon1_->SetDisabled();
    Disable(feeder_falcon_.get());
    Disable(intake_roller_falcon_.get());
    Disable(climber_falcon_.get());
  }

  ::std::unique_ptr<::frc::VictorSP> hood_victor_, intake_joint_victor_,
      turret_victor_, washing_machine_control_panel_victor_;

  ::std::unique_ptr<::frc::TalonFX> accelerator_left_falcon_,
      accelerator_right_falcon_, finisher_falcon0_, finisher_falcon1_;

  ::std::unique_ptr<::ctre::phoenix6::hardware::TalonFX> intake_roller_falcon_,
      climber_falcon_, feeder_falcon_;
};

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

  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);
    sensor_reader.set_pwm_trigger(true);
    sensor_reader.set_drivetrain_left_encoder(make_encoder(0));
    sensor_reader.set_drivetrain_right_encoder(make_encoder(1));
    // TODO: pin numbers
    sensor_reader.set_hood_encoder(
        make_unique<frc::Encoder>(22, 23, false, frc::Encoder::k4X));

    sensor_reader.set_hood_absolute_pwm(make_unique<frc::DigitalInput>(25));
    sensor_reader.set_hood_single_turn_absolute_pwm(
        make_unique<frc::DigitalInput>(24));

    sensor_reader.set_intake_encoder(make_encoder(5));
    sensor_reader.set_intake_absolute_pwm(make_unique<frc::DigitalInput>(1));

    sensor_reader.set_turret_encoder(make_encoder(2));
    sensor_reader.set_turret_absolute_pwm(make_unique<frc::DigitalInput>(0));
    sensor_reader.set_turret_potentiometer(make_unique<frc::AnalogInput>(0));

    sensor_reader.set_finisher_encoder(
        make_unique<frc::Encoder>(3, 2, false, frc::Encoder::k4X));
    sensor_reader.set_left_accelerator_encoder(make_encoder(4));
    sensor_reader.set_right_accelerator_encoder(make_encoder(3));

    sensor_reader.set_ball_intake_beambreak(make_unique<frc::DigitalInput>(4));

    if (FLAGS_shooter_tuning) {
      sensor_reader.set_ball_beambreak_inputs(
          make_unique<frc::DigitalInput>(6), make_unique<frc::DigitalInput>(7));
    }

    AddLoop(&sensor_reader_event_loop);

    // Note: If ADIS16470 is plugged in directly to the roboRIO SPI port without
    // the Spartan Board, then trigger is on 26, reset 27, and chip select is
    // CS0.
    // TODO(james): Double check whether the above is still accurate/useful with
    // the ADIS16448. No reason it shouldn't be.
    frc::SPI::Port spi_port = frc::SPI::Port::kOnboardCS1;
    std::unique_ptr<frc::DigitalInput> imu_trigger;
    std::unique_ptr<frc::DigitalOutput> imu_reset;
    if (::aos::network::GetTeamNumber() ==
        constants::Values::kCodingRobotTeamNumber) {
      imu_trigger = make_unique<frc::DigitalInput>(26);
      imu_reset = make_unique<frc::DigitalOutput>(27);
      spi_port = frc::SPI::Port::kOnboardCS0;
    } else {
      imu_trigger = make_unique<frc::DigitalInput>(9);
      imu_reset = make_unique<frc::DigitalOutput>(8);
    }
    ::aos::ShmEventLoop imu_event_loop(&config.message());
    std::unique_ptr<frc971::wpilib::ADIS16448> old_imu;
    std::unique_ptr<frc971::wpilib::ADIS16470> new_imu;
    std::unique_ptr<frc::SPI> imu_spi;
    if (::aos::network::GetTeamNumber() !=
        constants::Values::kCodingRobotTeamNumber) {
      old_imu = make_unique<frc971::wpilib::ADIS16448>(
          &imu_event_loop, spi_port, imu_trigger.get());
      old_imu->SetDummySPI(frc::SPI::Port::kOnboardCS2);
      old_imu->set_reset(imu_reset.get());
    } else {
      imu_spi = make_unique<frc::SPI>(spi_port);
      new_imu = make_unique<frc971::wpilib::ADIS16470>(
          &imu_event_loop, imu_spi.get(), imu_trigger.get(), imu_reset.get());
      sensor_reader.set_imu(new_imu.get());
    }
    AddLoop(&imu_event_loop);

    // Thread 4.
    ::aos::ShmEventLoop output_event_loop(&config.message());
    output_event_loop.set_name("output_writer");
    ::frc971::wpilib::DrivetrainWriter drivetrain_writer(&output_event_loop);
    drivetrain_writer.set_left_controller0(
        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(0)), true);
    drivetrain_writer.set_right_controller0(
        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(1)), false);

    SuperstructureWriter superstructure_writer(&output_event_loop);
    superstructure_writer.set_hood_victor(make_unique<frc::VictorSP>(8));
    superstructure_writer.set_intake_joint_victor(
        make_unique<frc::VictorSP>(2));
    superstructure_writer.set_intake_roller_falcon(
        make_unique<::ctre::phoenix6::hardware::TalonFX>(0));
    superstructure_writer.set_turret_victor(make_unique<frc::VictorSP>(7));
    superstructure_writer.set_feeder_falcon(
        make_unique<ctre::phoenix6::hardware::TalonFX>(1));
    superstructure_writer.set_washing_machine_control_panel_victor(
        make_unique<frc::VictorSP>(6));
    superstructure_writer.set_accelerator_left_falcon(
        make_unique<::frc::TalonFX>(5));
    superstructure_writer.set_accelerator_right_falcon(
        make_unique<::frc::TalonFX>(4));
    superstructure_writer.set_finisher_falcon0(make_unique<::frc::TalonFX>(9));
    superstructure_writer.set_finisher_falcon1(make_unique<::frc::TalonFX>(3));
    // TODO: check port
    superstructure_writer.set_climber_falcon(
        make_unique<::ctre::phoenix6::hardware::TalonFX>(2));

    AddLoop(&output_event_loop);

    RunLoops();
  }
};

}  // namespace wpilib
}  // namespace y2020

AOS_ROBOT_CLASS(::y2020::wpilib::WPILibRobot);
