/**
* @brief
websocket客户端管理器类

* @version
  V 1.0.0

* @author

* @date
  创建时间:  2018-08-17\n

* @note
  2018-08-17  创建类。\n

* @warning

* @bug
  
*/

#pragma once

#include <vector>
#include <string>
#include <map>
#include <boost/serialization/singleton.hpp>
#include "wsClient.h"
#include "ws_common.h"
#include "jsonBuilder.h"

namespace sys
{
	class wsClientMgr
	{
	private:
		std::vector<std::shared_ptr<wsClient>> __wsClientList;//ws客户端列表
		std::map<std::string,int>  __uriIndexList;//uri和客户端下标对应表
		std::string __LastError;//最新错误
		std::recursive_mutex __lock;//锁
		jsonBuilder __jsBuilder;//json生成器
	public:
		wsClientMgr();
		~wsClientMgr();
		/**
		* @brief		  重载[]运算符。
		* @param  [in] int index  下标\n
		* @return 下标对应的客户端连接\n
		*/
		std::shared_ptr<wsClient> operator[]( int index )
		{
			std::lock_guard<std::recursive_mutex> lock( __lock );
			std::shared_ptr<wsClient> pClient;

			if ( index < 0 )
			{
				return pClient;
			}

			if ( index < (int)__wsClientList.size() )
			{
				pClient = __wsClientList[index];
			}

			return pClient;
		}
		/**
		* @brief 构造函数。
		* @param  [in] const std::vector<std::string> uri_list  服务器uri列表\n
		* @param  [in] const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList  处理函数列表\n
		* @return 连接服务器是否成功\n @retval  0: 成功 -1:  失败\n
		*/
		void Build( const std::vector<std::string> uri_list, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList );

		/**
		* @brief 连接函数。
		* @param  [in] int time_out  超时(单位:秒),默认是3秒\n
		* @return 连接服务器是否成功.0: 成功 -1: 失败\n
		*/
		int connect( int time_out = 3 );
		/**
		* @brief 登录函数。
		*/
		void login();
		/**
		* @brief	发送数据函数。
		* @param  [in] const std::string & Cmd  要发送的命令\n
		* @param  [in] const std::string& Data  要发送的数据\n
		*/
		void send( const std::string & Cmd, const std::string & Data );
		/**
		* @brief 根据URI(连接串)获得对应的客户端函数。
		* @param  [in] const std::string& URI  \n
		* @return 获得的客户端连接\n
		*/
		std::shared_ptr<wsClient> GetClientByURI( const std::string& URI );
		/**
		* @brief	关闭函数。
		*/
		void close();
		/**
		* @brief	获得是否已连接服务器端函数。
		* @return 是否已连接服务器\n
		*/
		bool IsConnected();
		/**
		* @brief	获得是否已登录成功函数。
		* @return 是否已登录成功\n
		*/
		bool IsLogined();
		/**
		* @brief	获得Socket是否已打开函数。
		* @return Socket是否已打开\n
		*/
		bool IsSktOpened();
		/**
		* @brief		发送车辆进入特殊区域函数。
		* @param  [in] const _BASE_CARD_& stCard  卡结构体\n
		*/
		void SendSpecialAreaProcess( const _BASE_CARD_& stCard );

        /**
        * @brief 检测是否有连接断开,并重连
        * @param  [in] cur_time : 当前时刻 (秒)
        */
        void CheckClientConnect(unsigned int cur_time);

	private:
		/**
        * @brief 指定的wsClient重连webServer。
        * @param  [in] ws  : 连接
        */
		void Reconnect(std::shared_ptr<wsClient> & ws);

		/**
        * @brief 断开指定的wsCliennt
        * @param  [in] ws  : 连接
        */
		void Disconnet(std::shared_ptr<wsClient> & ws);
	};
}

//单件相关定义
typedef boost::serialization::singleton<sys::wsClientMgr> singleton_wsClientMgr;
#define swsClientMgr singleton_wsClientMgr::get_mutable_instance()
#define swsClientMgr_const singleton_wsClientMgr::get_const_instance()