/**
 *  相关参考资料
 *  DLTv1 传输协议：        https://www.autosar.org/fileadmin/standards/R20-11/FO/AUTOSAR_PRS_LogAndTraceProtocol.pdf
 *  DLTv2 传输协议：        https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_LogAndTraceProtocol.pdf
 *  COVESA 开源项目组：     https://github.com/COVESA
 *  dlt-viewer开源项目：    https://github.com/COVESA/dlt-viewer
 *  DLT文件结构设计定义：   https://github.com/COVESA/dlt-daemon/blob/master/doc/dlt_design_specification.md
 */

#ifndef __DLT_UTILITIES_HPP__
#define __DLT_UTILITIES_HPP__

#include "vector"
#include "string"

extern "C"
{
#include "stdint.h"
#include "stdio.h"
}

// DLT 类型定义
class DLT_Log
{
protected:
// 紧凑字节对齐
#pragma pack(1)

    //  The structure of the DLT file storage header. This header is used before each stored DLT message.
    // 存储头不是AUTOSAR规范定义的一部分，来自COVESA开源项目实现
    typedef struct
    {
        char pattern[4];      /**< This pattern should be DLT0x01 */
        uint32_t seconds;     /**< seconds since 1.1.1970 */
        int32_t microseconds; /**< Microseconds */
        char ecu[4];          /**< The ECU id is added, if it is not already in the DLT message itself */
    } DltStorageHeader;

    // The structure of the DLT standard header. This header is used in each DLT message.
    typedef struct
    {
        struct
        {
            uint8_t UEH : 1;  // Use Extended Header            1 启用扩展头        0 不启用
            uint8_t MSBF : 1; // Most Significant Byte First    1 Payload大端序列   0 小端序列
            uint8_t WEID : 1; // With ECU ID      (4 Byte)      1 包含ECU_ID        0 不含
            uint8_t WSID : 1; // With Session ID  (4 Byte)      1 包含会话 ID       0 不含
            uint8_t WTMS : 1; // With Timestamp   (4 Byte)      1 含时间戳          0 不含
            uint8_t VERS : 3; // Version Number DLT协议版本

        } htyp;       /**< This parameter contains several informations, see definitions below */
        uint8_t mcnt; /**< The message counter is increased with each sent DLT message */
        uint16_t len; /**< Length of the complete message, without storage header */
    } DltStandardHeader;

    // The structure of the DLT extra header parameters. Each parameter is sent only if enabled in htyp.
    typedef struct
    {
        char ecu[4];   /**< ECU id */
        uint32_t seid; /**< Session number */
        uint32_t tmsp; /**< Timestamp since system start in 0.1 milliseconds */
    } DltStandardHeaderExtra;

    // The structure of the DLT extended header. This header is only sent if enabled in htyp parameter.
    typedef struct
    {
        struct
        {
            uint8_t VERB : 1; // (Verbose)                  冗余模式   1 启用        0 不启用
            uint8_t MSTP : 3; // (Message Type)             消息类型
            uint8_t MTIN : 4; // (Message Type Info)        选定类型下的消息条目
        } msin;               /**< messsage info */
        uint8_t noar;         /**< number of arguments */
        char apid[4];         /**< application id */
        char ctid[4];         /**< context id */
    } DltExtendedHeader;
#pragma pack(0) // 恢复字节对齐

    // DLT消息条目结构定义
    typedef struct
    {
        DltStorageHeader storage_header;              // 存储头
        DltStandardHeader standard_header;            // 标准头
        DltStandardHeaderExtra standard_header_extra; // 标准头额外内容
        DltExtendedHeader extendedheader;             // 扩展头
        std::vector<uint8_t> payload;                 // 载荷
    } DLT_Msg;

protected:
    // 最长载荷长度
    size_t private_max_payload_len = 0;
    // 消息列表
    std::vector<DLT_Msg> private_msg_list;

public:
    // 只读引用
    const std::vector<DLT_Msg> &msg_list = this->private_msg_list;
    const size_t &max_payload_len = this->private_max_payload_len;

    /**
     * @brief 从文件加载
     * @param path_to_file 文件路径串
     * @return std::string 错误信息
     */
    std::string Load_From_File(const char *path_to_file);

    /**
     * @brief 以CSV格式导出到文件
     * @param path_to_file 文件路径串
     * @return std::string 错误信息
     */
    std::string Export_CSV(const char *path_to_file);

    // 对消息列表进行排序
    void Sort(void);

    // 清除缓存的信息
    void Clear(void);
};

#endif