using System.Collections.Generic;
using MessagePack;
#if Server
using Server.Core;

#else
using GameFramework;
#endif

namespace GameMessage
{
    [Message(MessageCode.ConnectAuthCode)]
    [MessagePackObject]
    public class ConnectAuthCode : MessageData
    {
        /// <summary>
        /// 验证码
        /// </summary>
        [Key(0)] public byte[] AuthCode;

#if Server
        public static ConnectAuthCode Create(byte[] authCode)
        {
            ConnectAuthCode connectAuthCode = ReferencePool.Fetch<ConnectAuthCode>();
            connectAuthCode.AuthCode = authCode;
            return connectAuthCode;
        }

        public override void Dispose()
        {
            this.AuthCode = null;
            ReferencePool.Recycle(this);
        }
#endif
    }

    [Message(MessageCode.ConnectSYN)]
    [MessagePackObject]
    public class ConnectSyn : MessageData
    {
        /// <summary>
        /// 验证码
        /// </summary>
        [Key(0)] public byte[] AuthCode;
        
#if GameClient
        public static ConnectSyn Create(byte[] authCode)
        {
            ConnectSyn connectSyn = ReferencePool.Acquire<ConnectSyn>();
            connectSyn.AuthCode = authCode;
            return connectSyn;
        }

        public override void Clear()
        {
            AuthCode = null;
        }
#endif
    }

    [Message(MessageCode.ConnectACK)]
    [MessagePackObject]
    public class ConnectAck : MessageData
    {
        /// <summary>
        /// 链接结果
        /// </summary>
        [Key(0)] public bool Result;

#if Server
        public static ConnectAck Create(bool result)
        {
            ConnectAck connectAck = ReferencePool.Fetch<ConnectAck>();
            connectAck.Result = result;
            return connectAck;
        }

        public override void Dispose()
        {
            ReferencePool.Recycle(this);
        }
#endif
    }

    [Message(MessageCode.ConnectFin)]
    [MessagePackObject]
    public class ConnectFin : MessageData
    {
#if GameClient
        public static ConnectFin Create()
        {
            return ReferencePool.Acquire<ConnectFin>();
        }
#endif
    }

    [Message(MessageCode.ServerFin)]
    [MessagePackObject]
    public class ServerFin : MessageData
    {
        /// <summary>
        /// 正常断开
        /// </summary>
        public const int FinCode_Normal = 0;

        /// <summary>
        /// 别处登录
        /// </summary>
        public const int FinCode_RemoteLogin = 1;
        
        [Key(0)] public int FinCode;

#if Server
        public static ServerFin Create(int finCode)
        {
            ServerFin serverFin = ReferencePool.Fetch<ServerFin>();
            serverFin.FinCode = finCode;
            return serverFin;
        }

        public override void Dispose()
        {
            ReferencePool.Recycle(this);
        }
#endif
    }

    /// <summary>
    /// 心跳包
    /// </summary>
    [Message(MessageCode.RouterHeartRequest)]
    [MessagePackObject]
    public class RouterHeartRequest : MessageData
    {
        /// <summary>
        /// 发送时间
        /// </summary>
        [Key(0)] public long SendTime;


#if GameClient
        public static RouterHeartRequest Create(long sendTime)
        {
            RouterHeartRequest request = ReferencePool.Acquire<RouterHeartRequest>();
            request.SendTime = sendTime;
            return request;
        }
#endif
    }

    [Message(MessageCode.RouterHeartResponse)]
    [MessagePackObject]
    public class RouterHeartResponse : MessageData
    {
        /// <summary>
        /// 发送时间
        /// </summary>
        [Key(0)] public long SendTime;

        /// <summary>
        /// 服务器链接信息
        /// </summary>
        [Key(1)] public List<ServerConnectInfo> ServerInfos;

#if Server
        public static RouterHeartResponse Create()
        {
            RouterHeartResponse routerHeartResponse = ReferencePool.Fetch<RouterHeartResponse>();
            return routerHeartResponse;
        }

        public override void Dispose()
        {
            //if (IsFromPool)
            {
                if (ServerInfos != null)
                {
                    foreach (var info in ServerInfos)
                    {
                        info.Dispose();
                    }
                }

                ServerInfos = null;
            }
            ReferencePool.Recycle(this);
        }
#endif
    }

    /// <summary>
    /// 服务器链接信息
    /// </summary>
    [MessagePackObject]
    public class ServerConnectInfo
#if Server
        : IReference
#endif
    {
        [IgnoreMember] public bool IsFromPool { get; set; }

        [IgnoreMember] public long ReferenceId { get; set; }

        /// <summary>
        /// 模块Id
        /// </summary>
        [Key(0)] public byte ModuleId;

        /// <summary>
        /// 模块数量
        /// </summary>
        [Key(1)] public byte NodeNum;

        /// <summary>
        /// 模块状态
        /// </summary>
        [Key(2)] public byte State;

        /// <summary>
        /// 链接中
        /// </summary>
        public const byte Connecting = 0;

        /// <summary>
        /// 连上了
        /// </summary>
        public const byte Open = 1;

        /// <summary>
        /// 链接已关闭
        /// </summary>
        public const byte Close = 2;

#if Server
        public static ServerConnectInfo Create()
        {
            return ReferencePool.Fetch<ServerConnectInfo>();
        }

        public void Dispose()
        {
            ReferencePool.Recycle(this);
        }
#endif
    }
}