/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */
#pragma once

#include <mrpt/comms/CClientTCPSocket.h>
#include <mrpt/comms/CServerTCPSocket.h>
#include <mrpt/config/CConfigFileBase.h>
#include <mrpt/hwdrivers/CGenericSensor.h>
#include <mrpt/obs/CObservationRFID.h>

#include <memory>

namespace mrpt::hwdrivers
{
/** This class implements an interface to an Impinj RFID reader. This object
 * connects to a program that does the actual communication with the receiver.
 * This is done because the manufacturer only provides libraries for C# and
 * Java. The program that runs the device must be started after this object
 * \ingroup mrpt_hwdrivers_grp
 */
class CImpinjRFID : public mrpt::hwdrivers::CGenericSensor
{
  DEFINE_GENERIC_SENSOR(CImpinjRFID)

 private:
  /** Poses (Antenna 1)
   */
  float pose_x_1, pose_y_1, pose_z_1, pose_yaw_1, pose_pitch_1, pose_roll_1;

  /** Poses (Antenna 2)
   */
  float pose_x_2, pose_y_2, pose_z_2, pose_yaw_2, pose_pitch_2, pose_roll_2;

  /** Server port
   */
  int port;

  /** IP of the module (usually 127.0.0.1)
   */
  std::string IPm;

  /** Reader name
   */
  std::string reader_name;

  /** Server socket (listens for the incoming connection)
   */
  std::unique_ptr<mrpt::comms::CServerTCPSocket> server;

  /** Client socket (handles the connection to the client)
   */
  std::unique_ptr<mrpt::comms::CClientTCPSocket> client;

  /** Driver executable path
   */
  std::string driver_path;

  /** Connection status
   */
  bool connected;

  /** start the external driver
   */
  void startDriver();

  static void dummy_startDriver(CImpinjRFID* o);

 public:
  /** Default constructor.
   */
  CImpinjRFID();
  ~CImpinjRFID() override;

  /** Connect to the reader.
   */
  void connect();

  void doProcess() override;

  void initialize() override;

  void loadConfig_sensorSpecific(
      const mrpt::config::CConfigFileBase& configSource, const std::string& section) override;

  /** Gets the information of the tags as a timestamped observation
   * NOTE: Deprecated, use getObservations instead. See CGenericSensor
   * documentation. This function is kept for internal use of the module
   * \return Returns true if the observation was correct, and false otherwise
   * \sa mrpt::hwdrivers::CGenericSensor
   */
  bool getObservation(mrpt::obs::CObservationRFID& obs);

  /** Close the connection to the reader.
   */
  void closeReader();
};  // End of class def.

}  // namespace mrpt::hwdrivers
