using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using CommonNetwork_ICE.Common;
using Slice;
using CommonNetwork_ICE.Util;
using CommonNetwork_ICE.handler;
using CommonLang.Protocol;
using CommonNetwork_ICE.Msg;
using CommonNetwork_ICE.Session;
using CommonLang.Log;
using CommonLang.Concurrent;

namespace CommonNetwork_ICE.Client
{
    /// <summary>
    /// ICE UDP客户端连接器,指定解码器,初始化本对象后可向指定服务器发送ICE消息,接收消息请先绑定会话侦听对象
    /// </summary>
    public class IceUdpClient : IceClientConnector
    {
        private static Logger log = LoggerFactory.GetLogger("IceUdpClient");

        public IceUdpClient(IceClientNetSession session)
            : this(session, Env.ICE_SEND_REMOTE_IP.Clone().ToString(), Env.ICE_SEND_REMOTE_PORT)
        {
        }

        public IceUdpClient(IceClientNetSession session, String ip, int port) : base(session, ip, port)
        {
            messageQueue = new ClientMessageQueue();
        }

        internal override SenderDisp_ getClientSendHandler(IceClientNetSession session, IceMessageCodec Codec)
        {
            ClientMsgHandlerUdpDelegate msgDelegate = new ClientMsgHandlerUdpDelegate(this, session);
            msgDelegate.Codec = Codec;
            return new ClientUdpSendHandler(msgDelegate);
        }

        /// <summary>
        /// 初始化ICE接收和发送端
        /// </summary>
        public override void Open(int localListenPort)
        {
            setLocalPort(localListenPort);
            this.ConnectToSever(Constants.COMM_TYPE_UDP);
            if (IsConnected)
            {
                messageQueue.Connector = Connector;
                messageQueue.Start();
            }
        }

        /// <summary>
        /// 关闭通讯通道
        /// </summary>
        public override void Close()
        {
            session.onClose();
            if (IsConnected)
            {
                messageQueue.End();
                CloseConnect();
            }
        }

        /// <summary>
        /// 具体的发送方法
        /// </summary>
        /// <param name="transMessage"></param>
        internal override bool SendTo(TransMessage transMessage)
        {
            if (transMessage.type == Constants.PACKET_HINGE)
            {
                messageQueue.AddMessage(transMessage);
            }
            else
            {
                try
                {
                    Connector.Sender.SendData(this.Connector.GetConnectorConfig().LocalPort, transMessage);
                }
                catch (Exception e)
                {
                    session.onException(e);
                    return false;
                }
            }
            return true;
        }
    }
}