// KeyList.cpp: implementation of the CKeyList class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "KeyList.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


#include "..\SmsCenterDlg.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CKeyList::CKeyList()
{
	m_IO = NULL;
	m_Key = NULL;
	m_Process = NULL;
	m_SQL      = NULL;
	m_IOIndex = 0;
	m_KeyIndex = 0;
	m_Process  = 0;
}

CKeyList::~CKeyList()
{
	Close();
}

IOCP_KEY_PTR CKeyList::GetBlank_Key()
{
	//从尾部找空闲的Key
	for ( int i=m_KeyIndex ; i<MAX_LOGINUSER ; i++ )
	{
		if ( (m_Key[i].socket == NULL || m_Key[i].socket==INVALID_SOCKET) &&
			 m_Key[i].lRandID==0)
		{
			m_KeyIndex = i+1;
			if ( m_KeyIndex>=MAX_LOGINUSER )
				m_KeyIndex = 0;
			m_Key[i].lRandID = rand();
			return &m_Key[i];
		}
	}

	//从头部找空闲的Key
	for ( i=0 ; i<m_KeyIndex && i<MAX_LOGINUSER ; i++ )
	{
		if ( (m_Key[i].socket == NULL || m_Key[i].socket==INVALID_SOCKET) &&
			 m_Key[i].lRandID==0)
		{
			m_KeyIndex = i+1;
			if ( m_KeyIndex>=MAX_LOGINUSER )
				m_KeyIndex = 0;
			m_Key[i].lRandID = rand();
			return &m_Key[i];
		}
	}
	return NULL;
}

IOCP_IO_PTR CKeyList::GetBlank_IO()
{
	//从尾部找空闲的IO
	for ( int i=m_IOIndex ; i<MAX_LOGINUSER ; i++ )
	{
		if ( (m_IO[i].socket == NULL || m_IO[i].socket==INVALID_SOCKET) &&
			 m_IO[i].lRandID==0)
		{
			m_IOIndex = i+1;
			if ( m_IOIndex>=MAX_LOGINUSER )
				m_IOIndex = 0;
			m_IO[i].lRandID = rand();
//			m_IO[i].IOS.lRandID=m_IO[i].lRandID;

			m_IO[i].m_bCheckup  = true;
			m_IO[i].m_bCompress = SENDDATA_COMPRESS;  //发送数据时是否压缩
			m_IO[i].m_lAgentID  =-100;       //代理商ID (默认为-100,未知代理商)
			m_IO[i].m_lAgentType=-100;     //代理商类型(默认为-100,未知代理商类型)

			return &m_IO[i];
		}
	}

	//从头部找空闲的IO
	for ( i=0 ; i<m_IOIndex && i<MAX_LOGINUSER ; i++ )
	{
		if ( (m_IO[i].socket == NULL || m_IO[i].socket==INVALID_SOCKET) &&
			 m_IO[i].lRandID==0 )
		{
			m_IOIndex = i+1;
			if ( m_IOIndex>=MAX_LOGINUSER )
				m_IOIndex = 0;
			m_IO[i].lRandID = rand();
//			m_IO[i].IOS.lRandID=m_IO[i].lRandID;
			return &m_IO[i];
		}
	}
	return NULL;
}

void CKeyList::RemoveAt_Key(IOCP_KEY_PTR pKey)
{
try
{
	if ( pKey )
	{
		if ( pKey< &m_Key[0] || pKey>&m_Key[MAX_LOGINUSER] )
			return ;

		//closesocket(pKey->socket);
		pKey->socket = 0;
		pKey->lRandID = 0;
	}
}catch(...)
{
	LOG_APPERROR(_T("T"));
	int i=0;
}
}

void CKeyList::RemoveAt_IO(IOCP_IO_PTR pIO)
{
try
{
	if ( pIO )
	{
		if ( pIO< &m_IO[0] || pIO>&m_IO[MAX_LOGINUSER] )
			return ;

		pIO->socket = 0;
		pIO->lRandID= 0;
//		pIO->IOS.lRandID = 0;

		if ( pIO->m_lUserID>0 )
		{
			TCHAR szMsg[256]={0};
			//退出
			if ( pIO->m_lID==199992 )  //正常退出
				_stprintf( szMsg , _T("[%d]%s-%s断线退出!") , pIO->m_lLocalPort,pIO->m_szCorpName,pIO->m_szLoginName);
			else
				_stprintf( szMsg ,  _T("[%d]%s-%s正常退出!") , pIO->m_lLocalPort,pIO->m_szCorpName,pIO->m_szLoginName);
			if ( AfxIsValidAddress(&m_pDlg->m_Setup,sizeof(m_pDlg->m_Setup),true) )
			{
				m_pDlg->AddLog( szMsg );
				m_pDlg->RefreshLogin();
			}
		}
		memset(pIO,0,sizeof(IOCP_IO));

	}
}catch(...)
{
	LOG_APPERROR(_T("T"));
	int i=0;
}
}

void CKeyList::Close_IO()
{
try
{
	if ( !m_IO )
		return ;
	//从尾部找空闲的IO
	for ( int i=0 ; i<MAX_LOGINUSER ; i++ )
	{
		if ( (m_IO[i].socket != NULL && m_IO[i].socket!=INVALID_SOCKET) )
		{
			closesocket(m_IO[i].socket);
		}
		RemoveAt_IO(&m_IO[i]);
	}
}
catch(...)
{
	LOG_APPERROR(_T("T"));
}
}

void CKeyList::Init(CSmsCenterDlg * pDlg)
{
	m_pDlg = pDlg;

	Close();  //先关闭再初始化

	if ( !m_IO )
	{
		long lSize = sizeof(IOCP_IO)*MAX_LOGINUSER;
		m_IO = new IOCP_IO[MAX_LOGINUSER];
		memset(m_IO,0,sizeof(IOCP_IO)*MAX_LOGINUSER);
	}
/*
	//初始化接收缓冲区
	for ( int i=0 ; i<MAX_LOGINUSER ; i++ )
	{
		m_IO[i].buf = new char[BUFFER_SIZE];
	}
*/
	
	if ( !m_Key )
	{
		m_Key = new IOCP_KEY[MAX_LOGINUSER];
		memset(m_Key,0,sizeof(IOCP_KEY)*MAX_LOGINUSER);
	}

/*	m_Process = new LPVOID[MAX_SQLCONNECT];
	memset(m_Process,0,sizeof(LPVOID)*MAX_SQLCONNECT);

	for ( int i=0 ; i<MAX_SQLCONNECT ; i++ )
	{
		CProcessSocket * pSocket = new CProcessSocket;
		m_Process[i] = (LPVOID)pSocket;
		pSocket->SetDlg(m_pDlg);
		pSocket->SetIndex(i);
	}
*/
	if ( !m_SQL )
	{
		m_SQL = new IOCP_SQL[MAX_SQLCONNECT];
		for ( int i=0 ; i<MAX_SQLCONNECT ; i++ )
		{
			m_SQL[i].bUse    = false;
			m_SQL[i].lRandID = 0;
			m_SQL[i].dwBeginUse = 0;
			m_SQL[i].dwEndUse = 0;
			m_SQL[i].lFuncID = 0;
			m_SQL[i].lUserID = 0;
			m_SQL[i].adoConnection.SetID(i);
#ifdef SMSCENTER_USECLIENT
			m_SQL[i].adoConnection.SetCursorLocation(adUseClient);  //设置为本地游标类型
#endif
		}
	}
}

CProcessSocket * CKeyList::GetBlank_Process()
{
try
{
/*
	for ( int k=0 ; k<3 ; k++ ) //重试3次,看能否找到。
	{
		for ( int i=0 ; i<MAX_SQLCONNECT ; i++ )
		{
			CProcessSocket * pProcess = (CProcessSocket *)m_Process[i];
			if (pProcess &&  !pProcess->m_bUse && pProcess->m_lRandID==0 )
			{
				if ( pProcess->m_adoConnection.isOK() && pProcess->m_AdoRS.isOK() && pProcess->m_AdoRS2.isOK() )
				{
					pProcess->m_bUse       = true;
					pProcess->m_lRandID    = rand();
					pProcess->m_dwBeginUse = ::GetTickCount();
					return pProcess;
				}
			}
		}
*/		
	/*
		//先查找前面10个,看能否找到空闲的
		for ( int j=0 ; j<3 ; j++ )
		{
			for ( int i=0 ; i<MIN_SQLCONNECT ; i++ )
			{
				CProcessSocket * pProcess = (CProcessSocket *)m_Process[i];
				if ( !pProcess->m_bUse && pProcess->m_lRandID==0 )
				{
					pProcess->m_bUse    = true;
					pProcess->m_lRandID = rand();
					pProcess->m_dwBeginUse = ::GetTickCount();
					return pProcess;
				}
			}
			Sleep(100);
		}
		for ( int i=MIN_SQLCONNECT ; i<MAX_SQLCONNECT ; i++ )
		{
			CProcessSocket * pProcess = (CProcessSocket *)m_Process[i];
			if ( !pProcess->m_bUse && pProcess->m_lRandID==0 )
			{
				pProcess->m_bUse    = true;
				pProcess->m_lRandID = rand();
				pProcess->m_dwBeginUse = ::GetTickCount();
				return pProcess;
			}
		}
*/
/*
		Sleep(500);
	}
*/
}
catch(...)
{
	LOG_APPERROR(_T("T"));
}
	return NULL;
}

void CKeyList::Close()
{
try
{
	Close_IO();

	if ( m_Key )
	{delete  []m_Key;m_Key=NULL;}
/*
	//删除接收缓冲区
	for ( int i=0 ; i<MAX_LOGINUSER ; i++ )
	{
		if ( m_IO[i].buf )
			delete m_IO[i].buf;
	}
*/
	if ( m_IO )
	{delete  []m_IO;m_IO=NULL;}

	if ( m_Process )
	{
		for ( int i=0 ; i<MAX_SQLCONNECT; i++ )
		{
			CProcessSocket * pSocket = (CProcessSocket *)m_Process[i];
			delete pSocket;
			m_Process[i] = NULL;
		}
		delete m_Process;
		m_Process = NULL;
	}
	if ( m_SQL )
	{delete  []m_SQL;m_SQL=NULL;}
}
catch(...)
{
	LOG_APPERROR(_T("T"));
}
}

IOCP_SQL_PTR CKeyList::GetBlank_SQL()
{
	for ( int j=0 ; j<3 ; j++ )
	{
		for ( int i=0 ; i<MAX_SQLCONNECT ; i++ )
		{
			if ( !m_SQL[i].bUse && m_SQL[i].lRandID==0 &&
				 m_SQL[i].adoConnection.isOK() )
			{
				m_SQL[i].bUse = true;
				m_SQL[i].lRandID = rand();
				m_SQL[i].dwBeginUse = GetTickCount();
				m_SQL[i].lFuncID = 0;
				m_SQL[i].lUserID = 0;
				return &m_SQL[i];
			}
		}
		Sleep(500);
	}
	return NULL;
}