////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// THIS IS AUTO-GENERATED CODE.  PLEASE DO NOT EDIT (File bug reports against tools).
///
/// Auto-generated by: Parameter Parser V5.5.1 (2411131018)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  parametereztuneworker.h
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PARAMETEREZTUNEWORKER_H
#define PARAMETEREZTUNEWORKER_H

#include <thread>

#include "parameterutils.h"
#include "parametertypes.h"
#include "parametereztunecom.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ParameterEzTuneWorker
///
/// @brief Ez Tune Worker
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class iEzTuneCallback;
class ParameterEzTuneWorker
{
public:
    static constexpr BYTE   const VERSION_MAJOR    = ParameterEzTuneCom::VERSION_MAJOR;
    static constexpr BYTE   const VERSION_MINOR    = ParameterEzTuneCom::VERSION_MINOR;
    static constexpr UINT32 const TAG_POS          = ParameterEzTuneCom::TAG_POS;
    static constexpr UINT32 const TAG_LEN          = ParameterEzTuneCom::TAG_LEN;
    static constexpr UINT32 const CMD_POS          = ParameterEzTuneCom::CMD_POS;
    static constexpr UINT32 const CMD_LEN          = ParameterEzTuneCom::CMD_LEN;
    static constexpr UINT32 const LEN_POS          = ParameterEzTuneCom::LEN_POS;
    static constexpr UINT32 const LEN_LEN          = ParameterEzTuneCom::LEN_LEN;
    static constexpr UINT32 const ID_POS           = ParameterEzTuneCom::ID_POS;
    static constexpr UINT32 const ID_LEN           = ParameterEzTuneCom::ID_LEN;
    static constexpr UINT32 const PAY_POS          = ParameterEzTuneCom::PAY_POS;
    static constexpr UINT32 const MAX_PACKET_LEN   = ParameterEzTuneCom::MAX_PACKET_LEN;
    static constexpr UINT32 const RECV_TIMEOUT_SEC = ParameterEzTuneCom::RECV_TIMEOUT_SEC;

    // Data Types:
    // bool   - Boolean value (0/1)
    // sbyte  - 8 bit signed integer
    // byte   - 8 bit unsigned integer
    // short  - 16 bit signed integer
    // ushort - 16 bit unsigned integer
    // INT32  - 32 bit signed integer
    // uint   - 32 bit unsigned integer
    // long   - 64 bit signed integer
    // ulong  - 64 bit unsigned integer
    // float  - 32 bit floating point
    // double - 64 bit floating point
    // string - nul terminated character string
    // struct - structure
    // module - Top level module structure
    // Command IDs are 1 byte, up to 256 unique commands are allowed, 7 are currently used
    // Request IDs are 4 bytes, and are provided in the request packet as a way to map the request to the response
    // Request IDs are use in commands that have unique request payloads, that are not included in the response
    // The Request ID (32 bits) allows the client and server to run multi threaded, and match the request with the response.
    // Start Tag (16 bit) is QC (0x5143), same as ExternalPort
    // Length (16 bit) is the length of the entire request or response packet including the Start Tag, Command and Length
    enum class Commands
    {
        EZTUNE_DEVICE_INFO,       // Device info Request: "<16 bit Start Tag><16 bit Command ID><16 bit Length>\0"
                                  // Device info Resonse: "<16 bit Start Tag><16 bit Command ID><16 bit Length><EzTune version 8 bit major><8 bit minor><64 bit device ID><Binary Tag>\0"
        EZTUNE_DATA_ACTIVE_MODES, // Active mode branchs Request: "<16 bit Start Tag><16 bit Command ID><16 bit Length>"
                                  // Active mode branchs Resonse: "<16 bit Start Tag><16 bit Command ID><16 bit Length><pipe '|' separated mode branch "Mode.SubMode">;...\0"
                                  // Example: "<0x01>Default|Sensor.1|Usecase.Snapshot|Feature1.None|Feature2.HLG|Scene.None|Effect.None\0"
        EZTUNE_DATA_CTRL_VALUES,  // Current control values Request: "<16 bit Start Tag><16 bit Command ID><16 bit Length>
                                  // Current control value Response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><comma separated list of all values Control Enum Value=Value>\0"
                                  // This information is availabe only to tuning set managers.  Not available for FD, Sensor Driver, etc. set managers
                                  // An empty string will be returned if this information is not available.
                                  // Example: "<16 bit Start Tag><16 bit Command ID>0=0,1=2.5,2=5;3=0.123;4=4.34,...\0"
        EZTUNE_DATA_MODES,        // Data Modes command Request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID><pipe separated mode branch>\0"
                                  // Example: "<16 bit Start Tag><16 bit Command ID><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ADRC\0"
                                  // Data Modes command Response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID><comma separated list of child modes>\0"
                                  // Example: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Feature2.None,Feature2.OISCapture,Feature2.MFNRPostFilter,Feature2.AIDenoiserMFNRBlend\0"
        EZTUNE_DATA_INFO,         // Data Info command Request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID><pipe separated mode branch>[:<comma separated variable list>]\0"
                                  // Module Example:   "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR\0"
                                  // Variable Example: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve\0"
                                  // Variable Example: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve.ai_mod_blend_lpf_tab\0"
                                  // Data Info command Response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID><pipe separated mode branch>:<semi-colon separated variable list "Name=Value">\0"
                                  // For simple types, the value will be included, for arrays you will need to use the get value command to get the values
                                  // Info: "<Name>[=<value>],<Type>[,<element count>[,<1 is optional>]]\0"
                                  // element count is present for arrays, is optional is present for optional arrays (can have 0 or 1 elements)
                                  // Module Example:  "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>abf40_bps_v2,module;anr14_ipe_v2,module;cc14_ipe_v2,module"
                                  // Varable Example: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>q_factor,uint;ai_mod_blend_lpf_tab,struct\0"
                                  // Varable Example: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>ai_mod_blend_lpf=10,uint,4\0"
        EZTUNE_DATA_GET_VALUES,   // Client Request for values for the specified colon separated mode::path: comma separated variable list
                                  // Example struct1 request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_core.mod_cc14_trigger_data\0"
                                  // Example struct2 request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve.ai_mod_blend_lpf_tab\0"
                                  // Example array request:   "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve.ai_mod_blend_lpf_tab:q_factor;ai_mod_blend_lpf\0"
                                  // Example element request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve.ai_mod_blend_lpf_tab:ai_mod_blend_lpf[2]\0"
                                  // Server Response for values, followed by a semi-colon separated nul terminated variable=value list
                                  // If array is requested, array data will be comma separated: "name=value,value,value,value\0"
                                  // If a structure is requested, all simple types will be returned, separated by a semi-colon: "name1=value1;name2=value2\0",
                                  // Only simple variable types will be returned and child structures will be skipped
                                  // Example struct1 response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>start=0;end=6\0"
                                  // Example struct2 response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>ai_mod_blend_lpf=13,17,22,24\0"
                                  // Example array response:   "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>ai_mod_blend_lpf=13,17,22,24\0"
                                  // Example element response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>ai_mod_blend_lpf[2]=22\0"
        EZTUNE_DATA_SET_VALUES,   // Client Request to set values for the specified colon separated mode:path: semi-colon separated variable=value list
                                  // If the variable path specified is a structure or array containing simple types, values specified in list will be set
                                  // You may set a single value, or all simple type array elements, separated by a comma
                                  // Array sizes cannot be modified.  If a partial set of array values are sent, the missing values will not be updated
                                  // Example struct1 request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_core:mod_cc14_trigger_data=0\0"
                                  // Example array request:   "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve:ai_mod_blend_lpf_tab:q_factor=2;ai_mod_blend_lpf=10,12,20,21\0"
                                  // Example element request: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 Bit Request ID>Default|Sensor.2|Usecase.Snapshot|Feature1.ISPHDR:cc14_ipe_v2.chromatix_cc14_reserve.ai_mod_blend_lpf_tab:ai_mod_blend_lpf[2]=20\0"
                                  // Server Set Values Response payload is the same as the TC_GET_VALUES_RSP payload, and can be used to validate the request
        EZTUNE_DATA_TRIG_VALUES,  // Current trigger values Request: "<16 bit Start Tag><16 bit Command ID><16 bit Length>\0"
                                  // Current trigger value Response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><comma separated list of all values trigger Enum Value=Value>\0"
                                  // This information is availabe only to tuning set managers.  Not available for FD, Sensor Driver, etc. set managers
                                  // An empty string will be returned if this information is not available.
                                  // Example: "<16 bit Start Tag><16 bit Command ID>0=0,1=2.5,2=5;3=0.123;4=4.34,...\0"
        EZTUNE_CUSTOM,            // Custom packet, when received, the IParameterDataAPI calls the custom packet handler
                                  // Custom command Request : "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 bit Request ID><payload>"
                                  // Custom command Response: "<16 bit Start Tag><16 bit Command ID><16 bit Length><32 bit Request ID><16 bit response><payload >"
                                  // If response is 0, then the custom handler is not installed or does not understand the request, and the payload will be empty
        EZTUNE_DATA_MAX
    };

    ParameterEzTuneWorker(IParameterDataAPI* dataAPI);
    ~ParameterEzTuneWorker();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Start
    ///
    /// @brief Starts the Ez Tune server
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void Start();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// StopEzSpectraTune
    ///
    /// @brief Stops the Ez Tune server
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void Stop();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsRunning
    ///
    /// @brief Returns EzTune server running state
    ///
    /// @brief Returns true if the EzTune service is running
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE bool IsRunning()
    {
        return m_readThread != nullptr;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetCallback
    ///
    /// @brief Sets the EzTune callback function
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE void SetCallback(iEzTuneCallback* callback)
    {
         m_callbackMutex.lock();
         m_callback = callback;
         m_callbackMutex.unlock();
    }

private:

    static void ReadFunction(
        void* worker);

    void ReadWorker();

    void ProcessDeviceInfo();

    void ProcessDataActiveModes();

    void ProcessDataControlValues();

    void ProcessDataTriggerValues();

    void ProcessDataModes(
        BYTE*  request,
        UINT32 length);

    void ProcessDataInfo(
        BYTE*  request,
        UINT32 length);

    void ProcessDataGetValues(
        BYTE*  request,
        UINT32 length);

    void ProcessDataSetValues(
        BYTE*  request,
        UINT32 length);

    void ProcessCustom(
        BYTE*  request,
        UINT32 length);

    static PARAMETER_INLINE bool IsPrintable(BYTE bt)
    {
        return (bt == 0 || (bt >= ' ' && bt <= '~'));
    }

    static bool IsPrintable(BYTE* bt, UINT32 len);

    IParameterDataAPI*           m_dataAPI;
    ParameterEzTuneCom* m_com;
    bool                m_exitData;
    UINT32              m_dataTimeout;
    std::thread*        m_readThread;
    iEzTuneCallback*    m_callback;
    std::mutex          m_callbackMutex;
};

#endif
