/*
 * Task_Base 是任务基类，用作不同的模块之间的通信载体。
 *	每一个模块创建一个任务子类，从Task_Base继承。
 *	然后任务子类自定义一些数据和读写数据的接口函数。
 *	然后在任务接受方实现 execute_task(Task_Base* p_laser_task)
 * */

#ifndef TASK_BASE_H
#define TASK_BASE_H
#include <string>
#include "../error_code/error_code.h"
#include <chrono>

//任务超时时间默认值10000ms，10秒
#define TASK_OVER_TIME_DEFAULT				10000

//任务类型
enum Task_type
{
	UNKNOW_TASK             =0,				//未知任务单//初始化,默认值
	LASER_MANGER_SCAN_TASK  =1,             //雷达管理模块的扫描任务,
	LASER_BASE_SCAN_TASK    =2,             //单个雷达的扫描任务,
    LOCATE_MANGER_TASK		=3,             //测量任务
    PLC_TASK                =4,             //上传PLC任务

    WANJI_MANAGER_TASK,						//万集雷达管理任务
	WANJI_LIDAR_SCAN,						//万集雷达扫描任务
	WANJI_LIDAR_DETECT,						//万集雷达定位任务

	VELODYNE_MANAGER_TASK,						//velodyne雷达管理任务
	VELODYNE_LIDAR_SCAN,						//velodyne雷达扫描任务
	VELODYNE_LIDAR_DETECT,						//velodyne雷达定位任务
    
};
//任务状态，如果任务故障，任务状态改为TASK_OVER，然后在m_task_error_manager 补充错误码。
enum Task_statu
{
    TASK_CREATED            =0,             //创建状态，默认值
    TASK_SIGNED             =1,             //已签收
    TASK_WORKING            =2,             //处理中
    TASK_OVER               =3,             //已结束
	TASK_ERROR              =11,             //任务错误

	//前面的状态由接收方选择, TASK_DEAD 则是发送方选择.
	TASK_DEAD               =12,             //当任务超时,发送方让任务死亡，

};

//任务单基类
class Task_Base
{
protected:
	//不允许构造基类，只允许子类构造，（多态）
	Task_Base();
public:
    ~Task_Base();

	//初始化任务单，必须初始化之后才可以使用，
	//    input:task_statu 任务状态
	//    input:task_statu_information 状态说明
	//    input:tast_receiver 接受对象
	//    input:task_over_time 超时时间
	Error_manager task_init(Task_statu task_statu,
					   std::string task_statu_information,
					   void* p_tast_receiver,
					   std::chrono::milliseconds task_over_time);

	//更新任务单
    //task_statu: 任务状态
    //statu_information:状态说明
    Error_manager update_statu(Task_statu task_statu,std::string statu_information="");

    //判断是否超时。返回true表示任务超时，返回false表示任务没有超时
    bool is_over_time();

	//判断是否结束, TASK_OVER  TASK_ERROR TASK_DEAD 都算结束
	bool is_task_end();

public:

	//获取 任务单id
	unsigned int  get_task_id();
	//设置 任务单id
//	void  set_task_id(unsigned int task_id) = delete;

    //获取 任务类型
    Task_type   get_task_type();
	//设置 任务类型
//	void   set_task_type(Task_type task_type) = delete;
    //获取 任务单状态
    Task_statu  get_task_statu();
	//设置 任务单状态
	void  set_task_statu(Task_statu task_statu);
    //获取 状态说明
    std::string get_task_statu_information();
	//设置 状态说明
	void set_task_statu_information(std::string task_statu_information);
	//获取 错误码，返回引用。
	Error_manager& get_task_error_manager();
	//设置 错误码
	void set_task_error_manager(Error_manager & error_manager);
	//比较覆盖错误码
	void compare_and_cover_task_error_manager(Error_manager & error_manager);

	//获取任务接收方
	void * get_tast_receiver();
	//设置任务接收方
	void set_tast_receiver(void * p_tast_receiver);
	//获取 任务创建的时间点
	std::chrono::system_clock::time_point get_task_start_time();
	//设置 任务创建的时间点
	void set_task_start_time(std::chrono::system_clock::time_point task_start_time);
	//获取 任务超时的时限
	std::chrono::milliseconds	get_task_over_time();
	//设置 任务超时的时限
	void	set_task_over_time(std::chrono::milliseconds task_over_time);


protected:
	unsigned int				m_task_id;						//任务id, 每次新建任务, 自动+1, 用于多任务的管理
    Task_type                   m_task_type;					//任务类型，不允许中途修改
    Task_statu                  m_task_statu;					//任务状态
    std::string					m_task_statu_information;		//任务状态说明
    void*						mp_tast_receiver;				//任务接收方，Task_Base并不分配和释放内存。
    //注：mp_tast_receiver是可选的，可以为NULL。如果为NULL，则需要task_command_manager去找到接收对象。

	std::chrono::system_clock::time_point 	m_task_start_time;	//任务创建的时间点
	std::chrono::milliseconds	m_task_over_time;				//任务超时的时限
	//注：std::chrono::system_clock::now();	//获取当前时间

	//错误码，任务故障信息，任务输出
	Error_manager               m_task_error_manager;
};

#endif //TASK_BASE_H

