#include <unistd.h>

#include <array>
#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/DriverStation.h"
#include "frc971/wpilib/ahal/Encoder.h"
#include "frc971/wpilib/ahal/TalonFX.h"
#include "frc971/wpilib/ahal/VictorSP.h"
#undef ERROR

#include "ctre/phoenix/cci/Diagnostics_CCI.h"

#include "aos/commonmath.h"
#include "aos/containers/sized_array.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/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/can_configuration_generated.h"
#include "frc971/constants/constants_sender_lib.h"
#include "frc971/control_loops/drivetrain/drivetrain_can_position_static.h"
#include "frc971/control_loops/drivetrain/drivetrain_position_generated.h"
#include "frc971/input/robot_state_generated.h"
#include "frc971/queues/gyro_generated.h"
#include "frc971/wpilib/buffered_pcm.h"
#include "frc971/wpilib/buffered_solenoid.h"
#include "frc971/wpilib/can_drivetrain_writer.h"
#include "frc971/wpilib/can_sensor_reader.h"
#include "frc971/wpilib/dma.h"
#include "frc971/wpilib/encoder_and_potentiometer.h"
#include "frc971/wpilib/generic_can_writer.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/talonfx.h"
#include "frc971/wpilib/wpilib_robot_base.h"
#include "y2024/constants.h"
#include "y2024/constants/constants_generated.h"
#include "y2024/control_loops/superstructure/superstructure_can_position_static.h"
#include "y2024/control_loops/superstructure/superstructure_output_generated.h"
#include "y2024/control_loops/superstructure/superstructure_position_generated.h"
#include "y2024/control_loops/superstructure/superstructure_position_static.h"

DEFINE_bool(ctre_diag_server, false,
            "If true, enable the diagnostics server for interacting with "
            "devices on the CAN bus using Phoenix Tuner");

using ::aos::monotonic_clock;
using ::frc971::CANConfiguration;
using ::frc971::control_loops::drivetrain::CANPositionStatic;
using ::frc971::wpilib::TalonFX;
using ::y2024::constants::Values;
namespace superstructure = ::y2024::control_loops::superstructure;
namespace drivetrain = ::y2024::control_loops::drivetrain;
namespace chrono = ::std::chrono;
using std::make_unique;

namespace y2024::wpilib {
namespace {

constexpr double kMaxBringupPower = 12.0;

double climber_pot_translate(double voltage) {
  return voltage * Values::kClimberPotRadiansPerVolt();
}

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

constexpr double kMaxFastEncoderPulsesPerSecond = std::max({
    Values::kMaxDrivetrainEncoderPulsesPerSecond(),
    Values::kMaxIntakePivotEncoderPulsesPerSecond(),
    Values::kMaxClimberEncoderPulsesPerSecond(),
});
static_assert(kMaxFastEncoderPulsesPerSecond <= 1300000,
              "fast encoders are too fast");

}  // namespace

// Class to send position messages with sensor readings to our loops.
class SensorReader : public ::frc971::wpilib::SensorReader {
 public:
  SensorReader(::aos::ShmEventLoop *event_loop,
               const Constants *robot_constants)
      : ::frc971::wpilib::SensorReader(event_loop),
        robot_constants_(CHECK_NOTNULL(robot_constants)),
        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::PositionStatic>(
                "/drivetrain")),
        gyro_sender_(event_loop->MakeSender<::frc971::sensors::GyroReading>(
            "/drivetrain")){};
  void Start() override { AddToDMA(&imu_yaw_rate_reader_); }

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

  void set_yaw_rate_input(::std::unique_ptr<frc::DigitalInput> sensor) {
    imu_yaw_rate_input_ = ::std::move(sensor);
    imu_yaw_rate_reader_.set_input(imu_yaw_rate_input_.get());
  }

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

      CopyPosition(intake_pivot_encoder_, builder->add_intake_pivot(),
                   Values::kIntakePivotEncoderCountsPerRevolution(),
                   Values::kIntakePivotEncoderRatio(), /* reversed: */ false);

      CopyPosition(climber_encoder_, builder->add_climber(),
                   Values::kClimberEncoderCountsPerRevolution(),
                   Values::kClimberEncoderRatio(), climber_pot_translate, true,
                   robot_constants_->robot()
                       ->climber_constants()
                       ->potentiometer_offset());

      builder->set_transfer_beambreak(transfer_beam_break_->Get());
      builder.CheckOk(builder.Send());
    }

    SendDrivetrainPosition(drivetrain_position_sender_.MakeStaticBuilder(),
                           drivetrain_velocity_translate,
                           constants::Values::DrivetrainEncoderToMeters, false,
                           false);

    {
      auto builder = gyro_sender_.MakeBuilder();
      ::frc971::sensors::GyroReading::Builder gyro_reading_builder =
          builder.MakeBuilder<::frc971::sensors::GyroReading>();
      // +/- 2000 deg / sec
      constexpr double kMaxVelocity = 4000;  // degrees / second
      constexpr double kVelocityRadiansPerSecond =
          kMaxVelocity / 360 * (2.0 * M_PI);

      // Only part of the full range is used to prevent being 100% on or off.
      constexpr double kScaledRangeLow = 0.1;
      constexpr double kScaledRangeHigh = 0.9;

      constexpr double kPWMFrequencyHz = 200;
      double velocity_duty_cycle =
          imu_yaw_rate_reader_.last_width() * kPWMFrequencyHz;

      constexpr double kDutyCycleScale =
          1 / (kScaledRangeHigh - kScaledRangeLow);
      // scale from 0.1 - 0.9 to 0 - 1
      double rescaled_velocity_duty_cycle =
          (velocity_duty_cycle - kScaledRangeLow) * kDutyCycleScale;

      if (!std::isnan(rescaled_velocity_duty_cycle)) {
        gyro_reading_builder.add_velocity((rescaled_velocity_duty_cycle - 0.5) *
                                          kVelocityRadiansPerSecond);
      }
      builder.CheckOk(builder.Send(gyro_reading_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()));
    }
  }

  void set_intake_pivot(::std::unique_ptr<frc::Encoder> encoder,
                        ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
    fast_encoder_filter_.Add(encoder.get());
    intake_pivot_encoder_.set_encoder(::std::move(encoder));
    intake_pivot_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
  }

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

  void set_climber(::std::unique_ptr<frc::Encoder> encoder,
                   ::std::unique_ptr<frc::DigitalInput> absolute_pwm,
                   ::std::unique_ptr<frc::AnalogInput> potentiometer) {
    fast_encoder_filter_.Add(encoder.get());
    climber_encoder_.set_encoder(::std::move(encoder));
    climber_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
    climber_encoder_.set_potentiometer(::std::move(potentiometer));
  }

 private:
  const Constants *robot_constants_;

  aos::Sender<frc971::autonomous::AutonomousMode> auto_mode_sender_;
  aos::Sender<superstructure::PositionStatic> superstructure_position_sender_;
  aos::Sender<frc971::control_loops::drivetrain::PositionStatic>
      drivetrain_position_sender_;
  ::aos::Sender<::frc971::sensors::GyroReading> gyro_sender_;

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

  std::unique_ptr<frc::DigitalInput> imu_yaw_rate_input_, transfer_beam_break_;

  frc971::wpilib::AbsoluteEncoder intake_pivot_encoder_;
  frc971::wpilib::AbsoluteEncoderAndPotentiometer climber_encoder_;

  frc971::wpilib::DMAPulseWidthReader imu_yaw_rate_reader_;
};

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");

    frc971::constants::WaitForConstants<y2024::Constants>(&config.message());

    ::aos::ShmEventLoop constant_fetcher_event_loop(&config.message());
    frc971::constants::ConstantsFetcher<Constants> constants_fetcher(
        &constant_fetcher_event_loop);
    const Constants *robot_constants = &constants_fetcher.constants();

    // 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, robot_constants);
    sensor_reader.set_pwm_trigger(true);
    sensor_reader.set_drivetrain_left_encoder(make_encoder(1));
    sensor_reader.set_drivetrain_right_encoder(make_encoder(0));
    sensor_reader.set_yaw_rate_input(make_unique<frc::DigitalInput>(0));
    // TODO: (niko) change values once robot is wired
    sensor_reader.set_intake_pivot(make_encoder(4),
                                   make_unique<frc::DigitalInput>(4));
    sensor_reader.set_transfer_beambreak(make_unique<frc::DigitalInput>(7));

    sensor_reader.set_climber(make_encoder(5),
                              make_unique<frc::DigitalInput>(5),
                              make_unique<frc::AnalogInput>(5));

    AddLoop(&sensor_reader_event_loop);

    // Thread 4.
    // Set up CAN.
    if (!FLAGS_ctre_diag_server) {
      c_Phoenix_Diagnostics_SetSecondsToStart(-1);
      c_Phoenix_Diagnostics_Dispose();
    }

    std::vector<ctre::phoenix6::BaseStatusSignal *> canivore_signal_registry;
    std::vector<ctre::phoenix6::BaseStatusSignal *> rio_signal_registry;

    const CurrentLimits *current_limits =
        robot_constants->common()->current_limits();

    std::shared_ptr<TalonFX> right_front = std::make_shared<TalonFX>(
        0, false, "Drivetrain Bus", &canivore_signal_registry,
        current_limits->drivetrain_supply_current_limit(),
        current_limits->drivetrain_stator_current_limit());
    std::shared_ptr<TalonFX> right_back = std::make_shared<TalonFX>(
        1, false, "Drivetrain Bus", &canivore_signal_registry,
        current_limits->drivetrain_supply_current_limit(),
        current_limits->drivetrain_stator_current_limit());
    std::shared_ptr<TalonFX> left_front = std::make_shared<TalonFX>(
        2, false, "Drivetrain Bus", &canivore_signal_registry,
        current_limits->drivetrain_supply_current_limit(),
        current_limits->drivetrain_stator_current_limit());
    std::shared_ptr<TalonFX> left_back = std::make_shared<TalonFX>(
        3, false, "Drivetrain Bus", &canivore_signal_registry,
        current_limits->drivetrain_supply_current_limit(),
        current_limits->drivetrain_stator_current_limit());
    std::shared_ptr<TalonFX> intake_pivot = std::make_shared<TalonFX>(
        4, false, "Drivetrain Bus", &canivore_signal_registry,
        current_limits->intake_pivot_stator_current_limit(),
        current_limits->intake_pivot_supply_current_limit());
    std::shared_ptr<TalonFX> intake_roller = std::make_shared<TalonFX>(
        5, false, "rio", &rio_signal_registry,
        current_limits->intake_roller_stator_current_limit(),
        current_limits->intake_roller_supply_current_limit());
    std::shared_ptr<TalonFX> transfer_roller = std::make_shared<TalonFX>(
        6, false, "rio", &rio_signal_registry,
        current_limits->transfer_roller_stator_current_limit(),
        current_limits->transfer_roller_supply_current_limit());
    std::shared_ptr<TalonFX> climber = std::make_shared<TalonFX>(
        7, false, "rio", &rio_signal_registry,
        current_limits->climber_stator_current_limit(),
        current_limits->climber_supply_current_limit());

    ctre::phoenix::platform::can::CANComm_SetRxSchedPriority(
        constants::Values::kDrivetrainRxPriority, true, "Drivetrain Bus");
    ctre::phoenix::platform::can::CANComm_SetTxSchedPriority(
        constants::Values::kDrivetrainTxPriority, true, "Drivetrain Bus");

    ::aos::ShmEventLoop can_sensor_reader_event_loop(&config.message());
    can_sensor_reader_event_loop.set_name("CANSensorReader");

    ::aos::ShmEventLoop rio_sensor_reader_event_loop(&config.message());
    rio_sensor_reader_event_loop.set_name("RioSensorReader");

    // Creating list of talonfx for CANSensorReader
    std::vector<std::shared_ptr<TalonFX>> drivetrain_talonfxs;
    std::vector<std::shared_ptr<TalonFX>> canivore_talonfxs;
    std::vector<std::shared_ptr<TalonFX>> rio_talonfxs;

    for (auto talonfx : {right_front, right_back, left_front, left_back}) {
      drivetrain_talonfxs.push_back(talonfx);
      canivore_talonfxs.push_back(talonfx);
    }

    for (auto talonfx : {intake_pivot}) {
      canivore_talonfxs.push_back(talonfx);
    }

    for (auto talonfx : {intake_roller, transfer_roller, climber}) {
      rio_talonfxs.push_back(talonfx);
    }

    aos::Sender<frc971::control_loops::drivetrain::CANPositionStatic>
        drivetrain_can_position_sender =
            can_sensor_reader_event_loop.MakeSender<
                frc971::control_loops::drivetrain::CANPositionStatic>(
                "/drivetrain");

    aos::Sender<y2024::control_loops::superstructure::CANPositionStatic>
        superstructure_can_position_sender =
            can_sensor_reader_event_loop.MakeSender<
                y2024::control_loops::superstructure::CANPositionStatic>(
                "/superstructure/canivore");

    frc971::wpilib::CANSensorReader canivore_can_sensor_reader(
        &can_sensor_reader_event_loop, std::move(canivore_signal_registry),
        canivore_talonfxs,
        [drivetrain_talonfxs, &intake_pivot, &drivetrain_can_position_sender,
         &superstructure_can_position_sender](
            ctre::phoenix::StatusCode status) {
          aos::Sender<frc971::control_loops::drivetrain::CANPositionStatic>::
              StaticBuilder drivetrain_can_builder =
                  drivetrain_can_position_sender.MakeStaticBuilder();

          auto drivetrain_falcon_vector =
              drivetrain_can_builder->add_talonfxs();

          CHECK(drivetrain_falcon_vector->reserve(drivetrain_talonfxs.size()));

          for (auto talonfx : drivetrain_talonfxs) {
            talonfx->SerializePosition(
                drivetrain_falcon_vector->emplace_back(),
                control_loops::drivetrain::kHighOutputRatio);
          }

          drivetrain_can_builder->set_timestamp(
              drivetrain_talonfxs.front()->GetTimestamp());
          drivetrain_can_builder->set_status(static_cast<int>(status));

          drivetrain_can_builder.CheckOk(drivetrain_can_builder.Send());

          aos::Sender<y2024::control_loops::superstructure::CANPositionStatic>::
              StaticBuilder superstructure_can_builder =
                  superstructure_can_position_sender.MakeStaticBuilder();

          intake_pivot->SerializePosition(
              superstructure_can_builder->add_intake_pivot(),
              control_loops::drivetrain::kHighOutputRatio);

          superstructure_can_builder->set_timestamp(
              intake_pivot->GetTimestamp());
          superstructure_can_builder->set_status(static_cast<int>(status));
          superstructure_can_builder.CheckOk(superstructure_can_builder.Send());
        });

    aos::Sender<y2024::control_loops::superstructure::CANPositionStatic>
        superstructure_rio_position_sender =
            rio_sensor_reader_event_loop.MakeSender<
                y2024::control_loops::superstructure::CANPositionStatic>(
                "/superstructure/rio");

    frc971::wpilib::CANSensorReader rio_can_sensor_reader(
        &rio_sensor_reader_event_loop, std::move(rio_signal_registry),
        rio_talonfxs,
        [&intake_roller, &transfer_roller, &climber,
         &superstructure_rio_position_sender](
            ctre::phoenix::StatusCode status) {
          aos::Sender<y2024::control_loops::superstructure::CANPositionStatic>::
              StaticBuilder superstructure_can_builder =
                  superstructure_rio_position_sender.MakeStaticBuilder();

          intake_roller->SerializePosition(
              superstructure_can_builder->add_intake_roller(),
              control_loops::drivetrain::kHighOutputRatio);
          transfer_roller->SerializePosition(
              superstructure_can_builder->add_transfer_roller(),
              control_loops::drivetrain::kHighOutputRatio);
          climber->SerializePosition(
              superstructure_can_builder->add_climber(),
              control_loops::drivetrain::kHighOutputRatio);

          superstructure_can_builder->set_timestamp(
              intake_roller->GetTimestamp());
          superstructure_can_builder->set_status(static_cast<int>(status));
          superstructure_can_builder.CheckOk(superstructure_can_builder.Send());
        });

    AddLoop(&can_sensor_reader_event_loop);
    AddLoop(&rio_sensor_reader_event_loop);

    // Thread 5.
    ::aos::ShmEventLoop can_output_event_loop(&config.message());
    can_output_event_loop.set_name("CANOutputWriter");

    frc971::wpilib::CANDrivetrainWriter can_drivetrain_writer(
        &can_output_event_loop);

    frc971::wpilib::GenericCANWriter<control_loops::superstructure::Output>
        can_superstructure_writer(
            &can_output_event_loop,
            [](const control_loops::superstructure::Output &output,
               const std::map<std::string_view, std::shared_ptr<TalonFX>>
                   &talonfx_map) {
              talonfx_map.find("intake_pivot")
                  ->second->WriteVoltage(output.intake_pivot_voltage());
              talonfx_map.find("intake_roller")
                  ->second->WriteVoltage(output.intake_roller_voltage());
              talonfx_map.find("transfer_roller")
                  ->second->WriteVoltage(output.transfer_roller_voltage());
              talonfx_map.find("climber")->second->WriteVoltage(
                  output.climber_voltage());
            });

    can_drivetrain_writer.set_talonfxs({right_front, right_back},
                                       {left_front, left_back});

    can_superstructure_writer.add_talonfx("intake_pivot", intake_pivot);
    can_superstructure_writer.add_talonfx("intake_roller", intake_roller);
    can_superstructure_writer.add_talonfx("transfer_roller", transfer_roller);
    can_superstructure_writer.add_talonfx("climber", climber);

    can_output_event_loop.MakeWatcher(
        "/roborio", [&can_drivetrain_writer, &can_superstructure_writer](
                        const frc971::CANConfiguration &configuration) {
          can_drivetrain_writer.HandleCANConfiguration(configuration);
          can_superstructure_writer.HandleCANConfiguration(configuration);
        });

    AddLoop(&can_output_event_loop);

    // Thread 6

    RunLoops();
  }
};

}  // namespace y2024::wpilib

AOS_ROBOT_CLASS(::y2024::wpilib::WPILibRobot);
