
//Error_code是错误码的底层通用模块，
//功能：用作故障分析和处理。

//用法：所有的功能接口函数return错误管理类，
//然后上层判断分析错误码，并进行故障处理。



#ifndef TEST_ERROR_ERROR_CODE_H
#define TEST_ERROR_ERROR_CODE_H

#include <string>
#include <string.h>
#include<iostream>

//错误管理类转化为字符串 的前缀，固定长度为58
//这个是由显示格式来确定的，如果要修改格式或者 Error_code长度超过8位，Error_level长度超过2位，折需要重新计算
#define ERROR_NAMAGER_TO_STRING_FRONT_LENGTH   58

//进程加锁的状态，
enum Lock_status
{
    UNLOCK      = 0,
    LOCK        = 1,
};

//设备使能状态，
enum Able_status
{
    UNABLE      = 0,
    ENABLE      = 1,
};

//数据是否为空
enum Empty_status
{
    NON_EMPTY   = 0,
    EMPTY       = 1,
};


//错误码的枚举，用来做故障分析
enum Error_code
{
    //成功，没有错误，默认值0
    SUCCESS                         = 0x00000000,


    //基本错误码，
    FAILED                          = 0x00000001,//失败
    ERROR                           = 0x00000002,//错误
    WARNING                         = 0x00000003,//警告
    PARTIAL_SUCCESS                 = 0x00000002,//部分成功


    NO_DATA                         = 0x00000010,//没有数据，传入参数容器内部没有数据时，
	INVALID_MESSAGE					= 0x00000011, //无效的消息,
    RESPONSE_TIMEOUT                = 0x00000012,
    PAUSE                           = 0x00000013,   //急停
    TASK_CANCEL                     = 0x00000014,   //任务取消

    DISCONNECT                      = 0x00000020,   //通讯中断/断开连接
    UNKNOW_STATU                    = 0x00000021,   //未知状态

    POINTER_IS_NULL                 = 0x00000101,//空指针
    PARAMETER_ERROR                 = 0x00000102,//参数错误，传入参数不符合规范时，
    POINTER_MALLOC_FAIL             = 0x00000103,//手动分配内存失败

    CLASS_BASE_FUNCTION_CANNOT_USE  = 0x00000201,//基类函数不允许使用，必须使用子类的

	CONTAINER_IS_TERMINATE			= 0x00000301,//容器被终止




//    错误码的规范，
//    错误码是int型，32位，十六进制。
//    例如0x12345678
//    12表示功能模块，例如:laser雷达模块               	框架制定
//    34表示文件名称，例如:laser_livox.cpp             框架制定
//    56表示具体的类，例如:class laser_livox           个人制定
//    78表示类的函数，例如:laser_livox::start();       个人制定
//    注：错误码的制定从1开始，不要从0开始，
//        0用作错误码的基数，用来位运算，来判断错误码的范围。

//    laser扫描模块
    LASER_ERROR_BASE                = 0x01000000,

//    laser_base基类
	LASER_BASE_ERROR_BASE			= 0x01010000,
    LASER_TASK_PARAMETER_ERROR      = 0x01010001,   //雷达基类模块, 任务输入参数错误
    LASER_CONNECT_FAILED,							//雷达基类模块, 连接失败
	LASER_START_FAILED,								//雷达基类模块, 开始扫描失败
	LASER_CHECK_FAILED,								//雷达基类模块, 检查失败
	LASER_STATUS_BUSY,								//雷达基类模块, 状态正忙
	LASER_STATUS_ERROR,								//雷达基类模块, 状态错误
	LASER_TASK_OVER_TIME,							//雷达基类模块, 任务超时
	LASER_QUEUE_ERROR,								//雷达基类模块, 数据缓存错误


//    laser_livox.cpp的错误码
    LIVOX_ERROR_BASE                = 0x01020000,
    LIVOX_START_FAILE,								//livox模块，开始扫描失败
	LIVOX_TASK_TYPE_ERROR,							//livox模块，任务类型错误
	lIVOX_CANNOT_PUSH_DATA,							//livox模块，不能添加扫描的数据
	lIVOX_CHECK_FAILED,								//livox模块，检查失败
	lIVOX_STATUS_BUSY,								//livox模块，状态正忙
	lIVOX_STATUS_ERROR,								//livox模块，状态错误

	//laser_manager 雷达管理模块
	LASER_MANAGER_ERROR_BASE						= 0x01030000,
	LASER_MANAGER_READ_PROTOBUF_ERROR,				//雷达管理模块，读取参数错误
	LASER_MANAGER_STATUS_BUSY,						//雷达管理模块，状态正忙
	LASER_MANAGER_STATUS_ERROR,						//雷达管理模块，状态错误
	LASER_MANAGER_TASK_TYPE_ERROR,					//雷达管理模块，任务类型错误
	LASER_MANAGER_IS_NOT_READY,						//雷达管理模块，不在准备状态
	LASER_MANAGER_LASER_INDEX_ERRPR,				//雷达管理模块，雷达索引错误，编号错误。
	LASER_MANAGER_TASK_OVER_TIME,					//雷达管理模块，任务超时
	LASER_MANAGER_LASER_INDEX_REPEAT,				//雷达管理模块，需要扫描的雷达索引重复,可忽略的错误,提示作用

//livox_driver 雷达livox驱动模块
	LIVOX_DRIVER_ERROR_BASE							= 0x01040000,
	LIVOX_DRIVER_SN_REPEAT,							//livox驱动模块, 雷达广播码重复
	LIVOX_DRIVER_SN_ERROR,							//livox驱动模块, 雷达广播码错误
	LIVOX_SKD_INIT_FAILED,							//livox驱动模块, livox_sdk初始化失败
	LIVOX_DRIVER_NOT_READY,							//livox驱动模块, livox没有准备好.




    //locate 定位模块,
	LOCATER_ERROR_BASE                				= 0x03000000,

	//LASER_MANAGER 定位管理模块
	LOCATER_MANAGER_ERROR_BASE                		= 0x03010000,
    LOCATER_MSG_TABLE_NOT_EXIST ,                                   //测量反馈未找到相应的请求(致命)
    LOCATER_MSG_RESPONSE_TYPE_ERROR,                                //测量反馈消息类型错误(致命)
    LOCATER_MSG_RESPONSE_INFO_ERROR,
    LOCATER_MSG_REQUEST_CANCELED,
    LOCATER_MSG_REQUEST_INVALID,
    LOCATER_MSG_RESPONSE_HAS_NO_REQUEST,
    LOCATER_MSG_REQUEST_REPEATED,

   /*
    * parkspace error code
    */
    PARKSPACE_REQUEST_MSG_TYPE_ERROR                = 0x04010000,
    PARKSPACE_ALLOCMSG_RESPONSE_HAS_NO_REQUEST,
    PARKSPACE_SEARCHMSG_RESPONSE_HAS_NO_REQUEST,
    PARKSPACE_RELEASEMSG_RESPONSE_HAS_NO_REQUEST,
    PARKSPACE_ALLOC_REQUEST_INVALID,
    PARKSPACE_SEARCH_REQUEST_INVALID,
    PARKSPACE_RELEASE_REQUEST_INVALID,

    PARKSPACE_ALLOC_REQUEST_REPEATED,
    PARKSPACE_SEARCH_REQUEST_REPEATED,
    PARKSPACE_RELEASE_REQUEST_REPEATED,

    PARKSPACE_ALLOC_RESPONSE_TYPE_ERROR,
    PARKSPACE_SEARCH_RESPONSE_TYPE_ERROR,
    PARKSPACE_RELEASE_RESPONSE_TYPE_ERROR,

    PARKSPACE_ALLOC_RESPONSE_INFO_ERROR,
    PARKSPACE_SEARCH_RESPONSE_INFO_ERROR,
    PARKSPACE_RELEASE_RESPONSE_INFO_ERROR,

    PARKSPACE_ALLOC_REQUEST_CANCELED,
    PARKSPACE_SEARCH_REQUEST_CANCELED,
    PARKSPACE_RELEASE_REQUEST_CANCELED,


	//Communication module, 通信模块
	COMMUNICATION_BASE_ERROR_BASE					= 0x11010000,
	COMMUNICATION_READ_PROTOBUF_ERROR,				//模块，读取参数错误
	COMMUNICATION_BIND_ERROR,
	COMMUNICATION_CONNECT_ERROR,
	COMMUNICATION_ANALYSIS_TIME_OUT,									//解析超时,
	COMMUNICATION_EXCUTER_IS_BUSY,										//处理器正忙, 请稍等


	//system module, 系统模块
	SYSTEM_EXECUTOR_ERROR_BASE						= 0x12010000,		//系统执行模块,
	SYSTEM_EXECUTOR_PARSE_ERROR,										//系统执行模块, 解析消息错误
	SYSTEM_EXECUTOR_STATUS_BUSY,										//系统执行模块, 状态正忙
	SYSTEM_EXECUTOR_STATUS_ERROR,										//系统执行模块, 状态错误
	SYSTEM_EXECUTOR_CHECK_ERROR,										//系统执行模块, 检查错误



	//Communication can module, can通信模块
	CAN_BASE_ERROR_BASE								= 0x15010000,		//can通信模块错误基地址
	CAN_READ_PROTOBUF_ERROR,											//can通信模块, 读取参数错误
	CAN_INDEX_REPEAT,
	CAN_INIT_ERROR,														//can初始化失败
	CAN_RUN_ERROR,														//can启动失败

	//motor 电机驱动器模块
	MOTOR_DRIVER_ERROR_BASE							= 0x16010000,		//电机驱动器模块, 错误基地址
	MOTOR_DRIVER_DEVICE_ERROR,											//电机驱动器模块, 设备故障
	MOTOR_DRIVER_COMMUNICATION_ERROR,									//电机驱动器模块, 通信故障

	//motor 电机管理模块
	MOTOR_MANAGER_ERROR_BASE						= 0x16020000,		//电机管理模块, 错误基地址
	MOTOR_MANAGER_READ_PROTOBUF_ERROR, 									//电机管理模块, 读取prototxt错误
	MOTOR_MANAGER_INDEX_REPEAT,											//电机管理模块, 设备索引重复,可忽略的错误,提示作用
	MOTOR_MANAGER_STATUS_ERROR,
};

//错误等级，用来做故障处理
enum Error_level
{
//    正常，没有错误，默认值0
    NORMAL                = 0,


//    轻微故障,可忽略的故障，NEGLIGIBLE_ERROR
//    提示作用，不做任何处理，不影响代码的流程，
//    用作一些不重要的事件，即使出错也不会影响到系统功能，
//    例如：文件保存错误，等
    NEGLIGIBLE_ERROR      = 1,


//    一般故障，MINOR_ERROR
//    用作底层功能函数的错误返回，表示该功能函数执行失败，
//    返回给应用层之后，需要做故障分析和处理，
//    例如：雷达数据传输失败，应用层就需要进行重新扫描，或者重连，或者重置参数等。
    MINOR_ERROR           = 2,


//    严重故障，MAJOR_ERROR
//    用作应用层的任务事件的结果，表示该功能模块失败。
//    通常是底层函数返回一般故障之后，应用层无法处理并解决故障，此时就要进行故障升级，
//    从一般故障升级为严重故障，然后进行回退流程，回退已经执行的操作，最终回到故障待机状态。
//    需要外部清除故障，并复位至正常待机状态，才能恢复功能的使用。
//    例如：雷达扫描任务失败，且无法自动恢复。
    MAJOR_ERROR           = 3,


//    致命故障，CRITICAL_ERROR
//    系统出现致命错误。导致系统无法正常运行，
//    此时系统应该紧急停机，执行紧急流程，快速停机。
//    此时不允许再执行任何函数和任务指令，防止系统故障更加严重。
//    也不需要做任何错误处理了，快速执行紧急流程。
//    例如：内存错误，进程挂死，关键设备失控，监控设备报警，等
    CRITICAL_ERROR        = 4,
};


class Error_manager
{
public://外部接口函数
    //构造函数
    Error_manager();
    //拷贝构造
    Error_manager(const Error_manager & error_manager);
    //赋值构造
    Error_manager(Error_code error_code, Error_level error_level = NORMAL,
                  const char* p_error_description = NULL, int description_length = 0);
    //赋值构造
    Error_manager(Error_code error_code, Error_level error_level , std::string & error_aggregate_string);
    //析构函数
    ~Error_manager();

    //初始化
    void error_manager_init();
    //初始化
    void error_manager_init(Error_code error_code, Error_level error_level = NORMAL,
                            const char* p_error_description = NULL, int description_length = 0);
    //初始化
    void error_manager_init(Error_code error_code, Error_level error_level , std::string & error_aggregate_string);
    //重置
    void error_manager_reset(Error_code error_code, Error_level error_level = NORMAL,
                             const char* p_error_description = NULL, int description_length = 0);
    //重置
    void error_manager_reset(Error_code error_code, Error_level error_level , std::string & error_aggregate_string);
    //重置
    void error_manager_reset(const Error_manager & error_manager);
    //清除所有内容
    void error_manager_clear_all();

    //重载=
    Error_manager& operator=(const Error_manager & error_manager);
    //重载=，支持Error_manager和Error_code的直接转化，会清空错误等级和描述
    Error_manager& operator=(Error_code error_code);
    //重载==
    bool operator==(const Error_manager & error_manager);
    //重载==，支持Error_manager和Error_code的直接比较
    bool operator==(Error_code error_code);
    //重载!=
    bool operator!=(const Error_manager & error_manager);
    //重载!=，支持Error_manager和Error_code的直接比较
    bool operator!=(Error_code error_code);
	//重载<<，支持cout<<
	friend std::ostream & operator<<(std::ostream &out, Error_manager &error_manager);


    //获取错误码
    Error_code get_error_code();
    //获取错误等级
    Error_level get_error_level();
    //获取错误描述的指针，（浅拷贝）
    char* get_error_description();

    //复制错误描述，（深拷贝）
    //output：p_error_description     错误描述的字符串指针，不可以为NULL，必须要有实际的内存
    //output:description_length      错误描述的字符串长度，不可以为0，长度最好足够大，一般256即可。
    void copy_error_description(const char* p_error_description, int description_length);
    //复制错误描述，（深拷贝）
    //output：error_description_string     错误描述的string
    void copy_error_description(std::string & error_description_string);

    //设置错误码
    void set_error_code(Error_code error_code);
    //比较错误等级并升级，取高等级的结果
    void set_error_level_up(Error_level error_level);
    //比较错误等级并降级，取低等级的结果
    void set_error_level_down(Error_level error_level);
    //错误等级，设定到固定值
    void set_error_level_location(Error_level error_level);
    //设置错误描述
    void set_error_description(const char* p_error_description, int description_length = 0);
    //设置错误描述
    void set_error_description(std::string & error_description_string);

    //尾部追加错误描述
    void add_error_description(const char* p_error_description, int description_length = 0);
    //尾部追加错误描述
    void add_error_description(std::string & error_description_string);

    //比较错误是否相同，
    // 注：只比较错误码和等级
	bool is_equal_error_manager(const Error_manager & error_manager);
	//比较并覆盖错误，讲低级错误转为字符串存放于描述中，
	//如果错误相同，则保留this的，将输入参数转入描述。
	void compare_and_cover_error(const Error_manager & error_manager);
	//比较并覆盖错误，讲低级错误转为字符串存放于描述中，
	//如果错误相同，则保留this的，将输入参数转入描述。
	void compare_and_cover_error( Error_manager * p_error_manager);

	//将所有的错误信息，格式化为字符串，用作日志打印。
    //output：p_error_description     错误汇总的字符串指针，不可以为NULL，必须要有实际的内存
    //output:description_length      错误汇总的字符串长度，不可以为0，长度最好足够大，一般256即可。
    void translate_error_to_string(char* p_error_aggregate, int aggregate_length);
    //output：error_description_string     错误汇总的string
    void translate_error_to_string(std::string & error_aggregate_string);
    //错误码转字符串的简易版，可支持cout<<
    //return     错误汇总的string
    std::string to_string();



protected:
    Error_code              m_error_code;               //错误码
    Error_level             m_error_level;              //错误等级
    char*                   pm_error_description;       //错误描述
    int                     m_description_length;       //错误描述的字符长度

protected://内部功能函数
public:
    //释放错误描述的内存，
    void free_description();

    //重新分配错误描述的内存，并从外部拷贝新的（深拷贝）
    //input：p_error_description     错误描述的字符串指针，可以为NULL，
    //input:description_length      错误描述的字符串长度，如果为0，则从p_error_description里面获取有效的长度
    void reallocate_memory_and_copy_string(const char* p_error_description, int description_length = 0);

    //重新分配错误描述的内存，并从外部拷贝新的（深拷贝）
    //input：error_aggregate_string     错误描述的string
    void reallocate_memory_and_copy_string(std::string & error_aggregate_string);
};




#endif //TEST_ERROR_ERROR_CODE_H


