// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

#pragma once

#include <functional>

#include "wpi/commands2/Command.hpp"
#include "wpi/commands2/CommandHelper.hpp"
#include "wpi/commands2/Requirements.hpp"
#include "wpi/system/Notifier.hpp"
#include "wpi/units/time.hpp"

namespace wpi::cmd {
/**
 * A command that starts a notifier to run the given runnable periodically in a
 * separate thread. Has no end condition as-is; either subclass it or use
 * Command::WithTimeout(double) or Command::Until(BooleanSupplier) to
 * give it one.
 *
 * <p>WARNING: Do not use this class unless you are confident in your ability to
 * make the executed code thread-safe.  If you do not know what "thread-safe"
 * means, that is a good sign that you should not use this class.
 *
 * This class is provided by the Commands v2 VendorDep
 */
class NotifierCommand : public CommandHelper<Command, NotifierCommand> {
 public:
  /**
   * Creates a new NotifierCommand.
   *
   * @param toRun        the runnable for the notifier to run
   * @param period       the period at which the notifier should run
   * @param requirements the subsystems required by this command
   */
  NotifierCommand(std::function<void()> toRun, wpi::units::second_t period,
                  Requirements requirements = {});

  NotifierCommand(NotifierCommand&& other);

  NotifierCommand(const NotifierCommand& other);

  void Initialize() override;

  void End(bool interrupted) override;

 private:
  std::function<void()> m_toRun;
  wpi::Notifier m_notifier;
  wpi::units::second_t m_period;
};
}  // namespace wpi::cmd
