/******************************************************************************************
 * File Name  : Student.h                                                     *
 * Created   : 08/09/16                                                                   *
 * Author   : ChenWei                                                                     *
 * Model   : TSD                                                                          *
 * Description  :                                        								  *
 ******************************************************************************************/

#ifndef STUDENT_H_
#define STUDENT_H_

#include "TimeStamp.h"
#include "NetSSLClientWrapper.h"
#include "TSDCommon.h"
#include "OperationManager.h"
#include "LockScheduleData.h"
#include <ace/Reactor.h>
#include <ace/Timer_Queue.h>
#include <ParaXml.h>
#include <ace/ACE.h>
#include <list>
#include <string>
#include <ace/Recursive_Thread_Mutex.h>
#include <time.h>
#include "libsesdata.h"
using namespace LibSESData;
using namespace IPCAPI;

typedef struct Node
{
	unsigned long m_iLen;
	unsigned char* m_pucStr;
	Node(unsigned char* pucStr, unsigned long iLen)
	{
		m_iLen = iLen;
		m_pucStr = NULL;
		try
		{
			m_pucStr = new unsigned char[iLen];
			memset(m_pucStr, 0, iLen);
			memcpy(m_pucStr, pucStr, iLen);
		} catch (...)
		{
			CSESLog::WriteLine("Student::Node catch err",CSESLog::FATAL);
		}
		//m_pucStr = pucStr;
	}
	void Release()
	{

		if (NULL != m_pucStr)
		{
			delete m_pucStr;
		}
	}
	~Node()
	{
		if (NULL != m_pucStr)
		{
			delete m_pucStr;
		}
	}
	//
	//	Node(const Node& mnode)
	//	{
	//		int i=sizeof(m_pucStr);
	//		memcpy(m_pucStr,mnode.m_pucStr,sizeof(m_pucStr));
	//		//m_pucStr = mnode.m_pucStr;
	//		m_iLen = mnode.m_iLen;
	//	}
	//	Node operator=(const Node& mnode)
	//	{
	//		memcpy(m_pucStr,mnode.m_pucStr,sizeof(m_pucStr));
	//		//m_pucStr = mnode.m_pucStr;
	//		m_iLen = mnode.m_iLen;
	//	}

} Node_t;
//
//class Node
//{
//public:
//	unsigned long m_iLen;
//	unsigned char* m_pucStr;
//	Node(unsigned char* pucStr, unsigned long iLen)
//	{
//		m_iLen = iLen;
//		//memcpy(m_pucStr, pucStr, 4);
//		m_pucStr = pucStr;
//		//m_pucStr = pucStr;
//	}
//
//	//
//	Node(const Node& mnode)
//	{
//		//int i = sizeof(m_pucStr);
//		//memcpy(m_pucStr, mnode.m_pucStr, sizeof(m_pucStr));
//		m_pucStr = mnode.m_pucStr;
//		m_iLen = mnode.m_iLen;
//	}
//	Node operator=(const Node& mnode)
//	{
//		//memcpy(m_pucStr,mnode.m_pucStr,sizeof(m_pucStr));
//		//
//		m_pucStr = mnode.m_pucStr;
//		m_iLen = mnode.m_iLen;
//	}
//
//};
//Node_t;

class Student: public ACE_Event_Handler
{
public:
	Student();

	virtual ~Student();

public:

	virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask);

	virtual int handle_signal(int signum, siginfo_t * = 0, ucontext_t * = 0);

	virtual int handle_exception(ACE_HANDLE handle);

	virtual int handle_input(ACE_HANDLE handle);

	virtual int handle_output(ACE_HANDLE handle);

	virtual int handle_timeout(const ACE_Time_Value &current_time,
			const void *act = 0);

	virtual ACE_HANDLE get_handle(void) const;

public:
	void Schedule_timer();

	void Close();

	bool Timeout(const time_t& newTime)
	{
		bool bReturn = false;

		if ((newTime - m_TimerOld) > STUDENT_HEARTTIMEOUT)
		{
			CSESLog::WriteLine(newTime, "Student::handle_timeout-->newTime:");
			CSESLog::WriteLine(m_TimerOld,
					"Student::handle_timeout-->m_TimerOld:");
			bReturn = true;
		}
		else
		{
			CSESLog::WriteLine(newTime, "Student::handle_timeout-->newTime:");
			CSESLog::WriteLine(m_TimerOld,
					"Student::handle_timeout-->m_TimerOld:");
		}
		if (m_bHandle_input)
		{
			bReturn = false;
		}
		return bReturn;
	}

	bool Recv(std::string & msg);

	//	bool Send(std::string & msg, int iTimeout);
	//
	//	bool Send(std::string & msg);

	bool Send(unsigned char* pucStr, unsigned long iLen);

	void SetConn(CNetSSLClientWrapper & cNetSSLClientWrapper);

	void GetStudentID(std::string & studentID) const;

	void SetStudentID(const std::string & id);

	StudentInfo_t* GetStudentInfo_t();

	void SetStudentInfo_t(const StudentInfo_t& studentInfo_t);
	void SetLockPolicy(std::string lockPolicy);
	void GetLockPolicy(std::string& lockPolicy);
	//For StuMgr
	void UpdateStudentStatus(int iLock, int istates);
	void UpdateLockPolicyData(long int lastUpdateTime, std::string deployname);
	int MsgListSize();

	void SetDisconnectStatus(int DisconnectStatus);
	int GetDisconnectStatus();
	void SetAllowStatus(int AllowStatus);
	int GetAllowStatus();
	void SetDel(bool bDel)
	{
		m_RectorLock.acquire();
		m_bDel = bDel;
		m_RectorLock.release();
	}
private:
	StudentInfo_t m_StudentInfo_t;
	LibSESData::CLockScheduleData m_LockScheduleData;
	CNetSSLClientWrapper *conn;
	time_t m_TimerOld;
	std::string m_StudentID;
	int m_iDisconnectStatus;
	int m_iAllowStatus;
	std::list<std::string> m_SendMsgList;
	ACE_Recursive_Thread_Mutex m_SendMsgListLock;
	ACE_Recursive_Thread_Mutex m_SendLock;
	ACE_Recursive_Thread_Mutex m_RecvLock;
	ACE_Recursive_Thread_Mutex m_RectorLock;
	std::list<Node*> m_MsgNodeList;
	int iSend;
	int iOutPut;
	bool m_bHandle_input;
	//time m_updatatime;
	bool m_bDel;
};

#endif /*STUDENT_H_*/
