/* VectorNav HSI Calibration Library v1.0.0.2
 *
 * Copyright (c) 2018 VectorNav Technologies, LLC
 *
 * This source code is proprietary to and copyrighted by VectorNav Technologies, LLC and is
 * available solely under license from VectorNav. All rights reserved. If you do not have a
 * license to use this source code from VectorNav, any use hereof is strictly prohibited by
 * U.S. law and other applicable law. This source code is restricted for use solely with the
 * products of VectorNav and as otherwise set forth in any agreement with VectorNav. Any
 * disclosure of this source code to the public or to any third party is also prohibited.
 */
#ifndef _VN_SEARCHER_H_
#define _VN_SEARCHER_H_

#include "vnbool.h"
#include "vnint.h"
#include "vnserialport.h"
#include "vnevent.h"

#if defined(_MSC_VER)
  #pragma warning(push)
  #pragma warning(disable:4820)   /* Not concerned with tight data structure packing on Windows. */
#endif

/**\brief Information about a found sensor. */
struct VnFoundSensorInfo
{
  char portName[50];      /**< Associated port name. */
  uint32_t baudRate;      /**< Working baud rate found. */
  char productName[50];   /**< Product name. */
  bool rxAvailable;       /**< Indicates RX communication works (host can receive data from sensor). */
  bool txAvailable;       /**< Indicates TX communication works (sensor can receive data from host). */
};

/**\brief Used when performing a threaded sensor search. */
struct VnSearcherThreaded
{
  /** Event that will signal when a threaded sensor search is completed. */
  struct VnEvent finishedEvent;

  /** Used internally updating this data structure from multiple threads. */
  struct VnCriticalSection writeCS;

  /** Set to the number of sensors found after the search is completed. */
  size_t numOfSensorsFound;

  /** Number of elements available for storage in the <c>foundSensorInfoBuffer</c>. */
  size_t numElementsInFoundSensorInfoBuffer;

  /** Pointer to buffer to store information about found sensors. */
  struct VnFoundSensorInfo *foundSensorInfoBuffer;
};

#if defined(_MSC_VER)
  #pragma warning(pop)
#endif

#ifndef __cplusplus
typedef struct VnFoundSensorInfo VnFoundSensorInfo_t;
#endif

/**\brief Searches the system for any VectorNav sensors and returns information
 *     about the first one found.
 * \param[out] info Information about the found sensor.
 * \return Any errors encountered. <c>E_NONE</c> if a sensor was found.
 *     <c>E_NOT_FOUND</c> if no sensor was found. */
enum VnError
VnSearcher_findFirstSensor(
    struct VnFoundSensorInfo * const info);

/**\brief Searchers the system for any VectorNav sensors and returns information
 *     about all that are found.
 * \param[in] infoBuf Pointer to a buffer containing <c>VnFoundSensorInfo</c>.
 *     Information about all sensors found will be placed in this buffer.
 * \param[in/out] infoBufCount Provide with the number of elements in the
 *     <c>infoBuf</c> parameter. When the function returns, this will be updated
 *     with the number of sensors found.
 * \return Any errors encountered. If <c>E_BUFFER_TOO_SMALL</c> is returned, the
 *     <c>infoBuf</c> was too small to contain all of the found sensor info. */
enum VnError
VnSearcher_findAllSensors(
    struct VnFoundSensorInfo *infoBuf,
    size_t *infoBufCount);

/**\brief Searches the specified port for any attached VectorNav sensors.
 * \param[in] portName The name of the port to search.
 * \param[out] info Contains sensor connection information if a VectorNav
 *     sensor is found.
 * \return If a sensor is found, <c>E_NONE</c> will be returned. If no sensor
 *     if found <c>E_NOT_FOUND</c> will be returned. */
enum VnError
VnSearcher_searchPort(
    char const *portName,
    uint32_t *foundBaudRate,
    char *productNameBuf,
    size_t productNameBufLen,
    bool *rxAvailable,
    bool *txAvailable);

/**\brief Initializes a <c>VnSearcherThreaded</c> structure.
 * \param[in] searcher The structure to initialize.
 * \return Any errors encountered. */
/*enum VnError
VnSearcherThreaded_initialize(
    struct VnSearcherThreaded *searcher);*/

/**\brief Deinitializes a <c>VnSearcherThreaded</c> structure.
 * \param[in] searcher The structure to deinitialize.
 * \return Any errors encountered. */
/*enum VnError
VnSearcherThreaded_deinitialize(
    struct VnSearcherThreaded *searcher);*/

/**\brief Starts the threaded search operation.
 * \param[in] foundSensorInfoBuffer User-provided buffer for storing information
 *     about found sensors.
 * \param[in] elementCount Number of elements in <c>foundSensorInfoBuffer</c>.
 *     Will be set on return to the number of sensors found.
 * \return Any errors encountered. */
enum VnError
VnSearcher_search_threaded(
    struct VnFoundSensorInfo *foundSensorInfoBuffer,
    size_t *elementCount);

/**\brief Starts the asynchronous threaded search operation.
 * \param[in] searcher The associated <c>VnSearcherThreaded</c> object.
 * \param[in] foundSensorInfoBuffer User-provided buffer for storing information
 *     about found sensors.
 * \param[in] numElementsInFoundSensorInfoBuffer Number of elements in
 *     <c>foundSensorInfoBuffer</c>.
 * \return Any errors encountered. */
/* TODO: Implement. */
enum VnError
VnSearcherThreaded_search_start(
    struct VnSearcherThreaded *searcher,
    struct VnFoundSensorInfo *foundSensorInfoBuffer,
    size_t numElementsInFoundSensorInfoBuffer);

#endif
