using CommonNetwork_ICE.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonNetwork_ICE.Util;
using CommonServer.Server;
using CommonServer.Protocol;
using CommonLang.Log;
using CommonServer_ICE.Server;

namespace CommonServer_ICE.Session
{
    /// <summary>
    /// 服务器端Session管理器
    /// </summary>
    internal class SessionManager
    {
        private static Logger log = LoggerFactory.GetLogger("SessionManager");

        private static Dictionary<string, ISession> sessionMap = new Dictionary<string, ISession>();
        private static Dictionary<string, ISession> sessionMapByID = new Dictionary<string, ISession>();
        private static IceServerSessionExpireTask sessionExpireTask;

        /// <summary>
        /// 判断序列号为键的会话是否存在
        /// </summary>
        /// <param name="sessionId">序列号键</param>
        /// <returns></returns>
        public static ISession getSession(string sessionId)
        {
            ISession ret;
            if (sessionMapByID.TryGetValue(sessionId, out ret ))
            {
                return ret;
            }
            return null;
        }

        /// <summary>
        /// 根据IP地址和端口判断是否存在某个会话
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public static ISession getSession(String ip, int port, int recvPort)
        {
            string key = getSessionStrKey(ip, port, recvPort);
            ISession ret;
            if (sessionMap.TryGetValue(key, out ret))
            {
                return ret;
            }
            return null;
        }

        /// <summary>
        /// IP地址和端口为键增加会话
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="session"></param>
        private static void addSession(String ip, IceServerIoSession ioSession)
        {
            string key = getSessionStrKey(ip, ioSession.ClientSentDataPort, ioSession.ClientRecvDataPort);
            sessionMap.Add(key, ioSession);
            sessionMapByID.Add(ioSession.ID, ioSession);
            log.Info("新增会话,键:" + key);
        }

        /// <summary>
        /// 删除会话
        /// </summary>
        /// <param name="session"></param>
        public static  void removeSession(ISession session)
        {
            IceServerIoSession ioSession = (IceServerIoSession)session;
            IceConfig config = ioSession.Connector.GetConnectorConfig();
            string key = getSessionStrKey(config.RemoteIp, ioSession.ClientSentDataPort, ioSession.ClientRecvDataPort);
            if (sessionMap.ContainsKey(key))
            {
                sessionMap.Remove(key);
                sessionMapByID.Remove(session.ID);
            }
        }

        /// <summary>
        /// 判断指定会话是否存在
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        public static bool hasSession(ISession session)
        {
            return hasSession(session.ID);
        }

        /// <summary>
        /// 判断指定序列号的会话是否存在
        /// </summary>
        /// <param name="sessionId"></param>
        /// <returns></returns>
        public static bool hasSession(string sessionId)
        {
            if (sessionMapByID.ContainsKey(sessionId))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断传入会话对象是否存在
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        public static bool hasSession(IceServerIoSession session)
        {
            IceConfig config = session.Connector.GetConnectorConfig();
            return hasSession(config.RemoteIp, session.ClientSentDataPort, session.ClientRecvDataPort);
        }

        /// <summary>
        /// IP地址和端口为键获取会话
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public static bool hasSession(String ip, int port, int recvPort)
        {
            string key = getSessionStrKey(ip, port, recvPort);
            if (sessionMap.ContainsKey(key))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取所有会话
        /// </summary>
        /// <returns></returns>
        public static List<ISession> getAllSession()
        {
            return sessionMap.Values.ToList();
        }

        /// <summary>
        /// 创建Session
        /// </summary>
        /// <param name="server"></param>
        /// <param name="codec"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public static IceServerIoSession createSession(IceConnectServer server, String ip, int port, int recvPort)
        {
            IceServerIoSession session = new IceServerIoSession(server);
            session.ClientSentDataPort = port;
            session.ClientRecvDataPort = recvPort;
            addSession(ip, session);
            return session;
        }

        /// <summary>
        /// 生成基于IP地址和端口的会话存储键
        /// </summary>
        /// <param name="recvPort">发送方侦听端口</param>
        /// <returns></returns>
        private static string getSessionStrKey(String ip, int port, int recvPort)
        {
            return ip + ":" + recvPort;
            //return ip + ":" + port + ":" + recvPort;
        }

        /// <summary>
        /// 启动会话过期检测线程
        /// </summary>
        public static void StartSessionExpireTask()
        {
            sessionExpireTask = new IceServerSessionExpireTask();
            sessionExpireTask.Start();
        }

        /// <summary>
        /// 关闭会话过期检测线程
        /// </summary>
        public static void EndSessionExpireTask()
        {
            sessionExpireTask.End();
        }
    }
}