/**
 * \file    Mimic.hpp
 * \author  Silvan Murer
 * \date    24 September 2022
 * \copyright This code is licensed under MIT license (see LICENSE for details)
 * 
 * \brief   Mimic - Library for access GenICam based devices
 */

#ifndef INC_MIMIC
#define INC_MIMIC

#include "Mimic_Producer.hpp"
#include "Mimic_Exception.hpp"

#include <filesystem>
#include <stdint.h>
#include <string>

namespace spdlog {
	class logger; ///< forward declaration of internal used logger object
}

namespace mimic {

/**
* Main class of libMimic - Library for access GenICam based devices
*
* This class is the starting point for the access of a GenICam based device.
* It scans for available GenTL Producers on the local machine.
*/
class Mimic {
private:
	/**
	 * \brief default constructor used to create a Mimic object
	 */
	Mimic();

	/**
	 * \brief return a vector with the entries of the GENICAM_GENTLxy_PATH 
	 *        environment variable, where 'xy' is replaced with the application
	 *        bit size (32bit or 64bit)
	 */
	std::vector<std::filesystem::path> getGenICam_GenTL_Path();

	std::vector<std::filesystem::path> producerList; ///< internal list of GenICam producer path
	std::shared_ptr<spdlog::logger> logger; ///< shared pointer to a simple console logger

public:
	Mimic(Mimic const&) = delete;
	Mimic& operator=(Mimic const&) = delete;

	/**
	 * \brief destructor used to destroy/release the Mimic object
	 */
	~Mimic();
	
	/**
	 * \brief right now, Mimic is implemented as singleton. 
	 *        This returns the Mimic object
	 */
	static Mimic& getInstance();

	/**
	 * \brief function to reset the whole system
	 *
	 * A call to this function release all allocated memory and release all open connections.
	 */
	//void reset();
	
	/**
	 * \brief read the version string of the used Mimic library
	 *
	 * \return a string value including the version information
	 */
	std::string getVersion();
	
	/**
	 * \brief scan for available GenTL Producer
	 *
	 * GenTL defines the environment variable GENICAM_GENTL64_PATH 
	 * (or GENICAM_GENTL32_PATH for 32bit systems) which contains a list
	 * of directories containing GenTL producers (*.cti files).
	 * This function search for available GenTL producers on the platform.
	 *
	 * \return the number of available GenTL producers
	 */
	uint32_t update();
	
	/**
	 * \brief read the filename of a genTL producer
	 *
	 * This method returns the filename of the GenTL producer at the given index.
	 * Before calling this method, a call to update() is required.
	 *
	 * \param[in]     tlNo    zero based index of the GenTL producer
	 *
	 * \return a string containing the GenTL producer filename
	 */
	std::string getProducerFilename(uint32_t tlNo);

	/**
	 * \brief read the path of a genTL producer
	 *
	 * This method returns the absolut path of the GenTL producer at the given index.
	 * Before calling this method, a call to update() is required.
	 *
	 * \param[in]     tlNo    zero based index of the GenTL producer
	 *
	 * \return a string containing the GenTL producer path
	 */
	std::string getProducerPath(uint32_t tlNo);

	/**
	 * \brief read the name of a genTL producer
	 * 
	 * This method reads the GenTL producer name at the given index.
	 * Before calling this method, a call to update() is required.
	 * 
	 * \param[in]     tlNo    zero based index of the GenTL producer
	 *
	 * \return a string containing the GenTL producer name
	 */
	std::string getProducerName(uint32_t tlNo);
	
	/**
	 * \brief open a GenTL producer on a given index
	 *
	 * Open a detected GenTL producer. 
	 * Before calling this method, a call to update() is required.
	 *
	 * \param[in]     tlNo    zero based index of the GenTL producer
	 *
	 * \return Mimic_Producer object of the GenTL producer
	 */
	Mimic_Producer openProducer(uint32_t tlNo);

	/**
	 * \brief open a GenTL producer on a given path
	 *
	 * Open a GenTL producer on a given path, without searching for it
	 * in the GenTL environment variable.
	 *
	 * \param[in]     producer    path including filename and extension of the genTL producer
	 *
	 * \return Mimic_Producer object of the GenTL producer
	 */
	Mimic_Producer openProducer(const std::filesystem::path producer);
};

} /* namespace mimic */

#endif
