#ifndef __SAT_EXECUTOR__
#define __SAT_EXECUTOR__

#pragma once

#include "CritSection.h"
#include "SATDevices.h"

// 用例xml;
typedef struct __ST_CASEITEM__
{
	bool result;
	std::string name;
	std::string data;
	std::vector<std::string> imgs;
	std::string log;
	std::string remark;
}STCaseItem, *pSTCaseItem;

class CSATExecutor
{
	CSATExecutor(void);
public:
	// 单例对象模式;
	static CSATExecutor* GetInstance()
	{
		static CSATExecutor* pInstance = NULL;
		if ( pInstance == NULL )
		{
			pInstance = new CSATExecutor;
		}

		return pInstance;
	}

	~CSATExecutor(void);

protected:
	// 线程控制句柄;
	HANDLE  m_hEventHearbeat;
	// 心跳线程句柄;
	HANDLE	m_hThreadHearbeat;
	// 线程控制句柄;
	HANDLE  m_hEventExcuteScript;
	// 执行线程句柄;
	HANDLE	m_hThreadExcuteScript;

	// 是否登录成功;
	BOOL	m_bLogin;

	ThreadSection	m_csTask;
	std::list<SATHTTP::STTask> m_vtTask;
	std::vector<SATHTTP::STDevice> m_vtDevice;
	SATHTTP::STLoginReq	m_stLoginReq;
	SATHTTP::STLoginResp	m_stLoginResp;
	// 执行器名称;
	std::string m_strActuatorName;

	// 任务是否存在;
	bool IsTaskExist(SATHTTP::STTask &task);
	// 是否有任务在执行;
	SATHTTP::STTask* IsThereATaskInProcess();
	// 提取未执行的任务;
	SATHTTP::STTask* GetFreeTask();
	// 移除已完成的任务;
	void DelFinishedTask();
	// 是否有用例脚本在执行;
	SATHTTP::STCase* IsCaseScriptProcess(std::vector<SATHTTP::STCase> &vtCases);
	// 提取未执行的用例;
	SATHTTP::STCase* GetFreeCaseScript(std::vector<SATHTTP::STCase> &vtCases);
	// 执行空闲新用例;
	SATHTTP::STCase* ExecuteFreeCaseScript(SATHTTP::STTask* pTask);
	
public:
	// 添加设备;
	void AddDevices(const SATDEV::STDevice &stDevice);
	// 删除设备;
	void DelDevices(const SATDEV::STDevice &stDevice);
	// 同步设备状态;
	void SynchDeviceStatus(std::string strDevName, SATDEV::DEVICE_USAGE_STATUS status);
	// 设备是否存在;
	bool IsDeviceExist(std::string strDevName);

public:
	// 登录;
	bool Login(std::string user, std::string password, std::string actuator, bool bLogin = true);
	// 登出;
	bool Logout(std::string user, std::string password);
	const SATHTTP::STLoginResp *GetLoginResp() const{ return &m_stLoginResp;};
	// 设置执行器名称;
	void SetActuatorName(const char *pszActuator){ if (pszActuator) m_strActuatorName = pszActuator;};
	// 更新设备信息;
	bool UpdateDevice();
	// 通知SAT任务开始;
	bool NotifyTaskStart(SATHTTP::STTask* pTask);
	// 上传用例图片;
	bool UploadCaseImg(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, std::string img);
	// 上传用例结果;
	bool UploadCaseLog(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase);
	// 上报用例测试项完成;
	bool ReportCaseItemFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, STCaseItem &caseItem);
	// 上报用例完成;
	bool ReportCaseFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase);
	// 上报用例结果;
	bool ReportCaseResult(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase);
	// 上传任务结果;
	bool UploadTaskLog(SATHTTP::STTask* pTask);
	// 上报任务开始;
	bool ReportTaskStart(SATHTTP::STTask* pTask);
	// 上报任务完成;
	bool ReportTaskFinish(SATHTTP::STTask* pTask);
	// 获取用例xml结果;
	bool GetCaseXMLResult(std::string xmlpath, std::vector<STCaseItem> &vtCaseItem);
	// 其他接口;
public:
	// 工作开始函数;	
	void StartWork();
	// 工作结束函数;
	void EndofWork();

	// 从db中加载任务;
	void LoadTaskInfo();
	// 心跳线程;
	static DWORD WINAPI HearbeatThread(LPVOID lpVoid);
	// 执行线程;
	static DWORD WINAPI ExecuteScriptThread(LPVOID lpVoid);
};


#endif //__SAT_EXECUTOR__