using ASHermed.SinoInterface.Api.IService.App;
using ASHermed.SinoInterface.Tools.Base;
using Newtonsoft.Json;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace ASHermed.SinoInterface.Api.Service.App
{
    public class RabbitMQService : IRabbitMQService
    {
        public ConnectionFactory connectionFactory;
        public static string Business = RabbitMQQueue.Business;
        public static string DelayBusiness = RabbitMQQueue.DelayBusiness;
        public RabbitMQService()
        {
            connectionFactory = RabbitMQConnection.CreateConnectFactory();
        }

        /// <summary>
        /// 推送消息
        /// </summary>
        /// <typeparam name="T">消息model</typeparam>
        /// <param name="queue">队列名</param>
        /// <param name="msg">消息</param>
        /// <param name="timeTolive">消息重试间隔</param>
        public void Publish<T>(RabbitMsgModel<T> pushModel, long timeTolive = 30000)
        {
            IConnection Connection = null;
            IModel Channel = null;
            try
            {
                new InitDeclare().Declare(Business, timeTolive);
                Connection = connectionFactory.CreateConnection();
                Channel = Connection.CreateModel();
                var properties = Channel.CreateBasicProperties();
                properties.DeliveryMode = 2;
                properties.Headers = new Dictionary<string, object>();
                var msgBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(pushModel));
                //Channel.ConfirmSelect();
                Channel.BasicPublish(RabbitMQExchange.BUSINESS_EXCHANGE, RabbitMQConfig.GetInstance().TAG + Business, properties, msgBytes);
                //if (Channel.WaitForConfirms())
                //{
                //    return true;
                //}
                //return false;
            }
            catch (System.Exception ex)
            {
                //TODO需接入log
                string str = ex.Message;
            }
            finally
            {
                //关闭连接
                if (Channel != null && Channel.IsOpen)
                {
                    Channel.Close();
                    Channel.Dispose();
                }
                if (Connection != null && Connection.IsOpen)
                {
                    Connection.Close();
                    Connection.Dispose();
                }
            }
        }
        /// <summary>
        /// 推送延时消息
        /// </summary>
        /// <typeparam name="T">消息model</typeparam>
        /// <param name="queue">队列名</param>
        /// <param name="msg">消息</param>
        /// <param name="delayTime">消息延时时间</param>
        /// <param name="timeTolive">消息重试间隔</param>
        public void Publish<T>(RabbitMsgModel<T> pushModel, long delayTime, long timeTolive = 30000)
        {
            IConnection Connection = null;
            IModel Channel = null;
            try
            {
                var mqConfig = RabbitMQConfig.GetInstance();

                new InitDeclare().Declare(DelayBusiness, timeTolive, true);
                Connection = connectionFactory.CreateConnection();
                Channel = Connection.CreateModel();
                var properties = Channel.CreateBasicProperties();
                properties.DeliveryMode = 2;
                properties.Headers = new Dictionary<string, object>() { { "x-delay", delayTime } };

                var msgBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(pushModel));
                //Channel.ConfirmSelect();
                Channel.BasicPublish(RabbitMQExchange.BUSINESS_DELAY_EXCHANGE, mqConfig.TAG + "delay_" + DelayBusiness, properties, msgBytes);
                //if (Channel.WaitForConfirms())
                //{
                //    return true;
                //}
                //return false;
            }
            catch (System.Exception ex)
            {
                //TODO需接入log
                string str = ex.Message;
            }
            finally
            {
                if (Channel != null && Channel.IsOpen)
                {
                    Channel.Close();
                    Channel.Dispose();
                }
                if (Connection != null && Connection.IsOpen)
                {
                    Connection.Close();
                    Connection.Dispose();
                }
            }
        }
    }
}
