/*! \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-2022 Neonode Technologies AB. All rights reserved.
 */

#ifndef TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H
#define TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H 1

#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.
 */
struct 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.
     *
     * Adds a HidPipeTransport to the internal list.
     * \n\n
     * 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.
     *
     * Calls hid_enumerate in the HidApi.
     * \n\n
     * 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.
     *
     * 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);
};

#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

#endif // TRANSPORT_HIDPIPETRANSPORT_HIDPIPETRANSPORTENUMERATION_H
