#ifndef LINUX_OBC_PTMECONFIG_H_
#define LINUX_OBC_PTMECONFIG_H_

#include "AxiPtmeConfig.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "linux/obc/PtmeConfig.h"

/**
 * @brief   Class to configure donwlink specific parameters in the PTME IP core.
 *
 * @author  J. Meier
 */
class PtmeConfig : public SystemObject, public HasReturnvaluesIF {
 public:
  /**
   * @brief Constructor
   *
   * ptmeAxiConfig  Pointer to object providing access to PTME configuration registers.
   */
  PtmeConfig(object_id_t opbjectId, AxiPtmeConfig* axiPtmeConfig);
  virtual ~PtmeConfig();

  virtual ReturnValue_t initialize() override;
  /**
   * @brief Changes the input frequency to the S-Band transceiver and thus the downlink rate
   *
   * @details This is the bitrate of the CADU clock and not the downlink which has twice the bitrate
   *          of the CADU clock due to the convolutional code added by the s-Band transceiver.
   */
  ReturnValue_t setRate(uint32_t bitRate);

  /**
   * @brief Will change the time the tx data signal is updated with respect to the tx clock
   *
   * @param invert  True -> Data signal will be updated on the falling edge (not desired by the
   *                Syrlinks)
   *                False -> Data signal updated on rising edge (default configuration and desired
   *                by the syrlinks)
   *
   * @return        REUTRN_OK if successful, otherwise error return value
   */
  ReturnValue_t invertTxClock(bool invert);

  /**
   * @brief Controls the tx clock manipulator of the PTME wrapper component
   *
   * @param enable  Manipulator will be enabled (this is also the default configuration)
   * @param disable Manipulator will be disabled
   *
   * @return        REUTRN_OK if successful, otherwise error return value
   */
  ReturnValue_t configTxManipulator(bool enable);

 private:
  static const uint8_t INTERFACE_ID = CLASS_ID::RATE_SETTER;

  //! [EXPORT] : [COMMENT] The commanded rate is not supported by the current FPGA design
  static const ReturnValue_t RATE_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
  //! [EXPORT] : [COMMENT] Bad bitrate has been commanded (e.g. 0)
  static const ReturnValue_t BAD_BIT_RATE = MAKE_RETURN_CODE(0xA1);
  //! [EXPORT] : [COMMENT] Failed to invert clock and thus change the time the data is updated with
  //! respect to the tx clock
  static const ReturnValue_t CLK_INVERSION_FAILED = MAKE_RETURN_CODE(0xA2);
  //! [EXPORT] : [COMMENT] Failed to change configuration bit of tx clock manipulator
  static const ReturnValue_t TX_MANIPULATOR_CONFIG_FAILED = MAKE_RETURN_CODE(0xA3);

  // Bitrate register field is only 8 bit wide
  static const uint32_t MAX_BITRATE = 0xFF;
  // Bit clock frequency of PMTE IP core in Hz
  static const uint32_t BIT_CLK_FREQ = 20000000;

  AxiPtmeConfig* axiPtmeConfig = nullptr;
};

#endif /* LINUX_OBC_PTMECONFIG_H_ */