#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 "absl/flags/flag.h"
#include "ctre/phoenix6/TalonFX.hpp"

#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_static.h"

ABSL_FLAG(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::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::PositionStatic>(
                "/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 (absl::GetFlag(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();

    {
      aos::Sender<superstructure::PositionStatic>::StaticBuilder builder =
          superstructure_position_sender_.MakeStaticBuilder();

      // TODO(alex): check new absolute encoder api.
      // Hood
      CopyPosition(hood_encoder_, builder->add_hood(),
                   Values::kHoodEncoderCountsPerRevolution(),
                   Values::kHoodEncoderRatio(),
                   Values::kHoodSingleTurnEncoderRatio(), false);
      // Intake
      CopyPosition(intake_joint_encoder_, builder->add_intake_joint(),
                   Values::kIntakeEncoderCountsPerRevolution(),
                   Values::kIntakeEncoderRatio(), false);
      // Turret
      CopyPosition(turret_encoder_, builder->add_turret(),
                   Values::kTurretEncoderCountsPerRevolution(),
                   Values::kTurretEncoderRatio(), turret_pot_translate, true,
                   values.turret.potentiometer_offset);
      // Shooter
      y2020::control_loops::superstructure::ShooterPositionStatic *shooter =
          builder->add_shooter();
      shooter->set_theta_finisher(
          encoder_translate(-finisher_encoder_->GetRaw(),
                            Values::kFinisherEncoderCountsPerRevolution(),
                            Values::kFinisherEncoderRatio()));

      shooter->set_theta_accelerator_left(
          encoder_translate(-left_accelerator_encoder_->GetRaw(),
                            Values::kAcceleratorEncoderCountsPerRevolution(),
                            Values::kAcceleratorEncoderRatio()));
      shooter->set_theta_accelerator_right(
          encoder_translate(right_accelerator_encoder_->GetRaw(),
                            Values::kAcceleratorEncoderCountsPerRevolution(),
                            Values::kAcceleratorEncoderRatio()));
      builder->set_intake_beambreak_triggered(ball_intake_beambreak_->Get());

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

    {
      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 (absl::GetFlag(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::PositionStatic> 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 (absl::GetFlag(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 y2020::wpilib

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