/*! \file
 * \brief Enumeration module to keep track of physically connected devices over USB HID.
 *
 * Allows connections to devices using Hid Pipe.
 *
 * \copyright
 * COPYRIGHT NOTICE: (c) 2021 Neonode Technologies AB. All rights reserved.
 *
 */

#if !defined(TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H) && !defined(CONTAINS_HIDPIPETRANSPORTENUMERATION)

#ifndef ZFORCECOMMON_H
    #error Please include "zForceCommon.h" before this file.
#endif // ZFORCECOMMON_H

// Forward declaration
typedef struct HidPipeTransport HidPipeTransport;

/*!
 * \sa struct HidPipeTransportEnumeration
 */
typedef struct HidPipeTransportEnumeration HidPipeTransportEnumeration;
/*!
 * \brief Struct containing the HidPipeTransportEnumeration information.
 *
 * HidPipeTransportEnumeration is a singleton class intended to be run in its own thread.
 * Singleton class.
 *
 */
struct HidPipeTransportEnumeration
{
#endif // !defined(TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORT_H) && !defined(CONTAINS_HIDPIPETRANSPORTENUMERATION)
#if !defined(TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H) || defined(CONTAINS_HIDPIPETRANSPORTENUMERATION)
    zForce                     * zForce;              //!< Pointer to zForce.
    Queue                      * Queue;               //!< Pointer to queue.
    void                       * Private;             //!< Pointer to private data structure.
    /*!
     * \brief Destroys the HidPipeTransportEnumeration.
     * \param self Pointer to the struct itself.
     * \return No return value.
     */
    void                     ( * Destructor)(HidPipeTransportEnumeration * self);
    /*!
     * \brief Adds a HidPipeTransport to the internal list.
     * On failure, errno is set.
     * - ::EOUTOFMEMORY - Memory allocation failed.
     * \param self Pointer to the struct itself.
     * \param transport Pointer to the HidPipeTransport to add.
     * \return Returns a boolean value.
     */
    bool                     ( * AddHidPipeTransport)(HidPipeTransportEnumeration * self, 
                                                      HidPipeTransport * transport);
    /*!
     * \brief Calls hid_enumerate in the HidApi.
     * On failure, errno is set.
     * - ::EOUTOFMEMORY - Memory allocation failed.
     * - ::EMUTEXNOTINITIALIZED - Mutex not initialized.
     * - ::EMUTEXLOCKFAILED - Mutex lock failed.
     * - ::EMUTEXUNLOCKFAILED - Mutex unlock failed.
     * \param self Pointer to the struct itself.
     * \param transport Pointer to the HidPipeTransport.
     * \param vid The vendor id of the device to search for.
     * \param pid The product id of the device to search for.
     * \return Returns a pointer to a linked list of all the present devices with the matching vid and pid.
     */
    struct hid_device_info * ( * Enumerate)(HidPipeTransportEnumeration * self,
                                            HidPipeTransport * transport, uint16_t vid, uint16_t pid);
    /*!
     * \brief Checks if there is anything in the internal list of HidPipeTransports.
     * \param self Pointer to the struct itself.
     * \return Returns true if the list is empty.
     */
    bool                     ( * IsTransportListEmpty)(HidPipeTransportEnumeration * self);
#endif // !defined(TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORT_H) || defined(CONTAINS_HIDPIPETRANSPORTENUMERATION)
#if !defined(TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H) && !defined(CONTAINS_HIDPIPETRANSPORTENUMERATION)
};

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
DLLINTERNAL HidPipeTransportEnumeration * HidPipeTransportEnumeration_GetInstance (void);

#if IS_TESTING == true
    #ifdef __linux__
    DLLINTERNAL void PublicHidPipeTransportEnumerationThreadEntryPoint (HidPipeTransportEnumeration *self);
    #elif defined(_WIN32)
    DLLINTERNAL DWORD WINAPI PublicHidPipeTransportEnumerationThreadEntryPoint (void * data);
    #endif // __linux__ elif _WIN32
#endif // IS_TESTING == true

#ifdef __cplusplus
}
#endif // __cplusplus

#define TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H
#endif // !defined(TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H) && !defined(CONTAINS_HIDPIPETRANSPORTENUMERATION)
