using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;

namespace RDH.PharmacyPlatform.Sync.Core
{
    /// <summary>
    /// 表示消息客户端的类
    /// </summary>
    public sealed class MessageClient
    {
        #region Fields
        private const String _RouteNodeKey = "route";
        #endregion

        #region Methods
        #region Public
        /// <summary>
        /// 向服务器发送注册消息
        /// </summary>
        public static String Register()
        {
            MessageData message = new MessageData();
            message.SourceId = Bootstrap.Config.LocalNodeId;
            message.TargetId = _RouteNodeKey;
            message.FilterType = MessageFilterType.Register;
            message.MessageContent = JsonSerializer.SerializeObject(new NodeRegisterInfo()
            {
                NodeId = message.SourceId,
                NodeGroupName = Bootstrap.Config.LocalNodeGroup,
                IsRegisterIn = true
            });
            return SendMessage(message);
        }
        /// <summary>
        /// 向服务器发送注销消息
        /// </summary>
        public static String UnRegister()
        {
            MessageData message = new MessageData();
            message.SourceId = Bootstrap.Config.LocalNodeId;
            message.TargetId = _RouteNodeKey;
            message.FilterType = MessageFilterType.Register;
            message.MessageContent = JsonSerializer.SerializeObject(new NodeRegisterInfo()
            {
                NodeId = message.SourceId,
                NodeGroupName = Bootstrap.Config.LocalNodeGroup,
            });
            return SendMessage(message);
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        public static String SendMessage(MessageData data)
        {
            if (Bootstrap.Config == null)
            {
                return "请先进行初始化";
            }
            //即时将待发送的消息持久化到本地
            Bootstrap.Log($"保存待发送的消息, id:{Thread.CurrentThread.ManagedThreadId}");
            try
            {
                Boolean saveFlag;
                using (ConnectionSessionScope conn = new ConnectionSessionScope(Bootstrap.DbConnectionString))
                {
                    MessageDataOutDAL messageDataOutDAL = new MessageDataOutDAL();
                    saveFlag = messageDataOutDAL.InsertModel(data);
                }
                Bootstrap.Log("保存结果：" + saveFlag.ToString());
                return saveFlag ? null : ("保存失败：" + Bootstrap.DbConnectionString);
            }
            catch (Exception ex)
            {
                Bootstrap.Log($"{ex.Message}\n{ex.StackTrace}");
                return ex.Message;
            }
        } 
        #endregion
        internal static String InternalSendMessage(MessageData data)
        {
            if (Bootstrap.Config == null)
            {
                return "请先进行初始化";
            }
            try
            {
                Debug.WriteLine($"发送消息, id:{Thread.CurrentThread.ManagedThreadId}");
                String jsonText = JsonSerializer.SerializeObject(data);
                Byte[] dataBytes = Encoding.UTF8.GetBytes(jsonText);
                //route
                //  如果消息中的route是业务路由器，则表示是由业务路由器发送的消息，其物理route等于消息中的route
                //  如果消息中的route不是业务路由器，则将物理route改为业务路由器进行中转
                //mandatory
                //  true:表示消息服务器将在ack之前触发return事件
                Bootstrap.MqChannel.BasicPublish(String.Empty, 
                    Bootstrap.Config.LocalNodeId == _RouteNodeKey ? data.TargetId : _RouteNodeKey, 
                    true, Bootstrap.ChannelProperties, dataBytes);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return null;
        } 
        #endregion
    }
}
