using CommonServer.Protocol;
using CommonServer.Server;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonNetwork_ICE.Common;
using CommonServer_ICE.Session;
using CommonLang.Protocol;
using CommonNetwork_ICE.Util;
using CommonServer_ICE.handler;
using CommonServer_ICE.Msg;
using System.Threading;
using CommonLang.Log;
using Slice;
using System.IO;
using CommonLang.IO;
using System.Collections.Specialized;

namespace CommonServer_ICE.Server
{
    /// <summary>
    /// ICE服务器:ISever实现类,实现服务器端ICE网络监听
    /// </summary>
    public abstract class IceConnectServer : IServer
    {
        private static Logger log = LoggerFactory.GetLogger("IceConnectServer");
        // 编码转换器
        private IPackageCodec codec = null;
        // 服务器配置
        private IceServerConfig config = null;
        // 服务器监听器
        protected IServerListener serverListener = null;
        // 服务器ICE监听对象
        protected IceConnector serverConnector = null;
        // 客户端连接地址
        private string clientConnectString;

        public IceConnectServer(IPackageCodec codec)
        {
            this.codec = codec;
            this.config = new IceServerConfig();
        }
        public string ClientConnectString
        {
            get { return clientConnectString; }
        }
        public IPackageCodec PackageCodec
        {
            get { return this.codec; }
        }

        /// <summary>
        /// 返回会话总数量
        /// </summary>
        public abstract int SessionCount { get; }

        /// <summary>
        /// 开启服务器
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="listener"></param>
        public void Open(NameValueCollection config, IServerListener listener)
        {
            string localHost = config.Get("ICE_RECV_LOCAL_IP");
            string localPort = config.Get("ICE_RECV_LOCAL_PORT");
            this.clientConnectString = config.Get("CLIENT_CONNECT_STRING");

            if (localHost == null || 
                localPort == null || 
                clientConnectString == null)
            {
                throw new Exception(string.Format(
                    @"Config Must Be Contains '{0}' and '{1}' and '{2}' fields !",
                    "ICE_RECV_LOCAL_IP",
                    "ICE_RECV_LOCAL_PORT",
                    "CLIENT_CONNECT_STRING"));
            }
            int l_port = 0;
            if (!int.TryParse(localPort, out l_port))
            {
                throw new Exception(string.Format(
                    @"Config '{0}' must be a digit value !",
                   "ICE_RECV_LOCAL_PORT"));
            }

            // 初始化服务器端设置
            this.config.Ip = localHost;
            this.config.Port = l_port;
            this.serverListener = listener;
            this.serverListener.OnInit(this);

            this.serverConnector = new IceConnector(
                Constants.SEND_INTERFACE_NAME,
                Constants.SERVER_SENDER_RECV_ADAPTER,
                "", 0,
                this.config.Ip,
                this.config.Port);

            this.serverConnector.GetConnectorConfig().LocalIp = localHost;
            this.serverConnector.GetConnectorConfig().LocalPort = l_port;

            Thread iceServerThread = new Thread(startIceServer);
            iceServerThread.Start();
        }

        /// <summary>
        /// 启动ICE服务器
        /// </summary>
        /// <returns></returns>
        internal abstract void StartIceServer();

        /// <summary>
        /// 获取传输类型
        /// </summary>
        /// <returns></returns>
        internal abstract int getCommType();

        /// <summary>
        /// 不阻塞主线程,启用新线程启动服务器
        /// </summary>
        private void startIceServer()
        {
            try
            {
                StartIceServer();
            }
            catch (Exception e)
            {
                Exception innerEx = e.InnerException;
                string msg = "";
                if (innerEx != null)
                {
                    msg = innerEx.Message;
                }
                else
                {
                    msg = e.Message;
                }
                log.Error("ICE服务器启动异常:" + msg);
                throw e;
            }
            finally
            {
                if (serverConnector.RecvConnector != null)
                {
                    serverConnector.Destroy();
                }
            }
        }

        /// <summary>
        /// 增加了一个新会话
        /// </summary>
        /// <param name="session"></param>
        internal void OnNewSessionConnected(IceServerIoSession session)
        {
            log.Trace("服务器新增加了一个会话,来自地址IP【" + session.GetRemoteAddress() + "】");
            ISessionListener sessionListener = serverListener.OnSessionConnected(session);
            session.bindSessionListener(sessionListener);
        }

        /// <summary>
        /// 释放服务器资源
        /// </summary>
        public abstract void Dispose();


        public IceServerConfig getServerConfig()
        {
            return this.config;
        }

        public abstract void Broadcast(IMessage message);

        public abstract bool HasSession(ISession session);

        public abstract ISession GetSessionByID(string sessionID);

        public abstract IEnumerable<ISession> GetSessions();
    }
}