/*========================== begin_copyright_notice ============================
Copyright (C) 2016-2021 Intel Corporation

SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/

/*!
 * @file GTPIn configuration (KNOB) interface for tools
 */

#ifndef _CLIENT_KNOB_H
#define _CLIENT_KNOB_H

#include <stddef.h>
#include <stdint.h>

#include "gtreplay_client.h"

#include "knob_defs.h"

#if defined(__cplusplus)
extern "C"
{
#endif

/*!
 * @ingroup KNOB
 * Create a new Knob argument
 * @param[in]   name        the unique identifier of the Knob
 * @param[in]   message     a description of the Knob to be printed in the help message
 * @param[in]   flags       a combination of KNOB_FLAG properties
 * @param[in]   symId       a single-symbol identifier of the Knob in the command line,
 *                          or \0 character if such identifier does not exist
 * @param[in]   knobType    the type of the Knob value(s)
 * @return  handle to the new Knob, or NULL if requested Knob cannot be created (e.g. due to name duplication)
 */
GTREPLAY_API
GTPinKnob KNOB_CreateArg(const char* name, const char* message, uint32_t flags, char symId, KNOB_TYPE knobType);

/*!
 * @ingroup KNOB
 * Find an existing Knob argument with the specified name
 * @param[in]   name           identifier of the requested Knob
 * @return  handle to the requested Knob, or NULL if a Knob with the specified name does not exist
 */
GTREPLAY_API
GTPinKnob KNOB_FindArg(const char* name);

/*!
 * @return Total number of elements in the sequence of Knob arguments
 */
GTREPLAY_API
uint32_t KNOB_NumArgs();

/*!
 * @ingroup KNOB
 * @return Knob argument at the specified location in the sequence of Knob arguments
 * @param[in]   pos             location in the sequence of Knob arguments. This could
 *                              be any integer in the [0, KNOB_NumArgs()) range
 */
GTREPLAY_API
GTPinKnob KNOB_GetArg(uint32_t pos);

/*!
 * @ingroup KNOB
 * @return the number of value elements associated with the Knob, or zero in case of failure
 * @note Vector-value Knob (KNOB_FLAG_VECTOR) may have multiple value elements, while
 *       scalar-value Knob has a single value element.
 * @ingroup KNOB
 * @param[in]   knob     the Knob to query
 */
GTREPLAY_API
uint32_t KNOB_NumValues(GTPinKnob knob);

/*!
 * Copy descriptor of the specified knob into structure pointed by 'dsc'
 */
GTREPLAY_API
KNOB_STATUS KNOB_GetDescriptor(GTPinKnob knob, KnobDescriptor* dsc);

/*!
 * @ingroup KNOB
 * Given a Knob, fetch its value element at the specified position.
 * @note Vector-value Knob (KNOB_FLAG_VECTOR) may have multiple value elements, while
 *       scalar-value Knob has a single value element and its position is zero.
 * @param[in]   knob     the Knob to be queried
 * @param[out]  value    pointer to the structure that receives the requested value and its type
 * @param[in]   index    the position of the requested element in the vector of values
 *
 * @pre     'index' is less than KNOB_NumValues(knob)
 * @return  success/failure status
 * @note For a Knob of type KNOB_TYPE_STRING, the value returned in the structure could be invalidated when
 *       the Knob is modified by a subsequent KNOB_AddValue() call.
 */
GTREPLAY_API
KNOB_STATUS KNOB_GetValue(GTPinKnob knob, KnobValue* value, uint32_t index);

/*!
 * @ingroup KNOB
 * Assign new value to the specified Knob.
 * If this Knob is associated with a vector of values, append the new value to the vector.
 * Otherwise, if this is a scalar Knob, replace the old value with the new one.
 * @param[in]   knob     the Knob to be modified
 * @param[in]   value    the new value of the Knob. Its type must match the type of the Knob,
 *                       as specified at Knob creation.
 * @return  Success/failure status
 */
GTREPLAY_API
KNOB_STATUS KNOB_AddValue(GTPinKnob knob, KnobValue* value);

/*!
 * @ingroup KNOB
 * Reset value of the specified Knob.
 * If 'knob' is associated with a vector of values, clear the vector. Otherwise, for scalar Knob, do nothing.
 * @return  Success/failure status
 */
GTREPLAY_API
KNOB_STATUS KNOB_Reset(GTPinKnob knob);

#if defined(__cplusplus)
}
#endif

#endif
