using SuperSocket.ClientEngine;
using System;
using System.Net;

namespace ET.Server
{
    [FriendOf(typeof(FastStreamComponent))]
    public static class FastStreamComponentSystem
    {
        public class FastStreamComponentAwakeSystem: AwakeSystem<FastStreamComponent>
        {
            protected override void Awake(FastStreamComponent self)
            {
                FastStreamComponent.Instance = self;

                self.FastStreamClient = new EasyClient();
                self.FastStreamClient.Initialize<FastStreamBuffer>(new FastStreamMessageDecoder(FastStreamMessageDecoder.LEN_HEAD), OnSessionDataReceived);
                self.FastStreamClient.NoDelay = true;
                self.FastStreamClient.ReceiveBufferSize = 10* 1024 * 1024;

                self.FastStreamClient.Connected += new EventHandler(OnSessionConnected);
                self.FastStreamClient.Error += new EventHandler<ErrorEventArgs>(OnSessionError);
                self.FastStreamClient.Closed += new EventHandler(OnSessionClosed);

                //IPAddress ipAddress = Dns.GetHostAddresses("localhost")[0];
                IPAddress ip = IPAddress.Parse("127.0.0.1");
                IPEndPoint endpoint = new IPEndPoint(ip, 3370);
                self.FastStreamClient.ConnectAsync(endpoint);
            }
        }

        public class FastStreamComponentDestroySystem: DestroySystem<FastStreamComponent>
        {
            protected override void Destroy(FastStreamComponent self)
            {
                Log.Info($"Ice component destroyed");
                self.FastStreamClient?.Close();
                self.FastStreamClient = null;
            }
        }

        //===component扩展=============
        public static void SendData(this FastStreamComponent self, string key, byte[] value)
        {
            ByteBuffer buff = ByteBuffer.Allocate(2048, true);
            buff.WriteShort((short)key.Length);
            buff.WriteInt(value.Length);
            buff.WriteBytes(key.ToUtf8());
            buff.WriteBytes(value);
            self.FastStreamClient.Send(new ArraySegment<byte>(buff.GetBuffer(), 0, buff.ReadableBytes));
        }
        //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        private static void OnSessionConnected(object sender, EventArgs e)
        {
            Log.Debug("fast stream session connected");
            FastStreamComponent.Instance.SendData("connetorId", ("bs-" + ConstGame.GameServerId.ToString()).ToUtf8());
        }

        private static void OnSessionDataReceived(FastStreamBuffer pack)
        {
            long usrid = (long)pack.Key;
            byte[] data = pack.Data;
            //Log.Debug($"receive fast stream data, uid({usrid}), msglen:{data.Length}");

            //找到此unit对应的Player(id相同)
            WNPlayer player = FastStreamComponent.Instance.DomainScene().GetComponent<GamePlayerComponent>().Get(usrid);
            if (player != null)
            {
                MessageHelper.SendToClient(player, new BattleEventPush() { key = (ushort)BattlePushCnst.FastStreamPush, data = data});
            }
            // else
            // {
            //     Log.Error($"Not found player({usrid}) @faststream data");
            // }
        }

        private static void OnSessionError(object sender, ErrorEventArgs e)
        {
            Log.Warning("fast stream session error");

            FastStreamComponent self = FastStreamComponent.Instance;
            //TODO: ReConnect战斗服
        }

        private static void OnSessionClosed(object sender, EventArgs e)
        {
            Log.Warning("fast stream session closed");
            //TODO: ReConnect战斗服
        }
    }


}