
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Formatter;

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

namespace MesWorkMqtt
{
    public class Mqtt
    {
        /// <summary>
        /// 
        /// </summary>
        public static IManagedMqttClient mqttClient = null;
        public static string MqttUrl = ConfigurationManager.AppSettings["MqttUrl"];
        /// <summary>
        /// 
        /// </summary>
        public  static string topic = "";


        /// <summary>
        /// 
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public  static async Task StartAsync()
        {
            string uri = MqttUrl;
            //127.0.0.1:18083,123
            var array = uri.Split(new char[] { ':', ',' });
            string mqttUser = "MisDataFun";
            string mqttPassword = "";
            var options = new MqttClientOptions
            {
                ClientId = "MisDataFun-200170511",
                ProtocolVersion = MqttProtocolVersion.V311,
                ChannelOptions = new MqttClientTcpOptions { Server = array[0], Port = Convert.ToInt32(array[1]) },
                CleanSession = false,
                SessionExpiryInterval = 300,
                KeepAlivePeriod = TimeSpan.FromSeconds(20),
                Credentials = new MqttClientCredentials
                {
                    Username = mqttUser,
                    Password = Encoding.UTF8.GetBytes(mqttPassword)
                }
            };
            mqttClient = new MqttFactory().CreateManagedMqttClient();

            //mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
            //mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
            //mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnSubscriberMessageReceived);
            await mqttClient.StartAsync(new ManagedMqttClientOptions { ClientOptions = options });
            topic = array[2];
            await mqttClient.SubscribeAsync(new MqttTopicFilter { Topic = topic });

        }

        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="publish_topic"></param>
        /// <param name="publish_msg"></param>
        /// <returns></returns>
        public  static async Task Publish(string publish_topic, string publish_msg)
        {
            if (mqttClient != null)
            {
                try
                {
                    await mqttClient.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(publish_topic).WithPayload(publish_msg).WithExactlyOnceQoS().Build());

                }
                catch (Exception err)
                {

                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="publish_topic"></param>
        /// <param name="publish_msg"></param>
        /// <returns></returns>
        public static async Task PublishQos0(string publish_topic, string publish_msg)
        {
            if (mqttClient != null)
            {
                await mqttClient.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(publish_topic).WithPayload(publish_msg).WithAtLeastOnceQoS().Build());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public  static async Task StopAsync()
        {
            if (mqttClient != null)
            {
                await mqttClient.UnsubscribeAsync(new string[] { topic });
                await mqttClient.StopAsync();
            }
        }
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="x"></param>
        //private static void OnSubscriberConnected(MqttClientConnectedEventArgs x)
        //{
        //    var rec = x.AuthenticateResult.ResultCode.ToString();
        //    // label_State.Text = rec;
        //}
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="x"></param>
        //private static void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs x)
        //{
        //    //var rec = x.AuthenticateResult.ResultCode.ToString();
        //    //label_State.Text = rec;
        //}
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="x"></param>
        //private static void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
        //{
        //    var rec = x.ApplicationMessage.ConvertPayloadToString();
        //    // txt_Rec.Text = txt_Rec.Text + rec + System.Environment.NewLine;

        //}



    }

    public class Mqtt2
    {
        /// <summary>
        /// 
        /// </summary>
        public IManagedMqttClient mqttClient = null;
        public string MqttUrl;
        /// <summary>
        /// 
        /// </summary>
        public string topic = "";

        public Mqtt2()
        {
            mqttClient = new MqttFactory().CreateManagedMqttClient();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public async Task StartAsync()
        {
            string uri = MqttUrl;
            //127.0.0.1:18083,123
            var array = uri.Split(new char[] { ':', ',' });
            string mqttUser = "";
            string mqttPassword = "";
            var options = new MqttClientOptions
            {
                ClientId = Guid.NewGuid().ToString(),
                ProtocolVersion = MqttProtocolVersion.V311,
                ChannelOptions = new MqttClientTcpOptions { Server = array[0], Port = Convert.ToInt32(array[1]) },
                CleanSession = true,
                KeepAlivePeriod = TimeSpan.FromSeconds(100),
                Credentials = new MqttClientCredentials
                {
                    Username = mqttUser,
                    Password = Encoding.UTF8.GetBytes(mqttPassword)
                }
            };
            //mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
            //mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
            //mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnSubscriberMessageReceived);
            await mqttClient.StartAsync(new ManagedMqttClientOptions { ClientOptions = options });
            //topic = array[2];
            await mqttClient.SubscribeAsync(new MqttTopicFilter { Topic = topic });

        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="publish_topic"></param>
        /// <param name="publish_msg"></param>
        /// <returns></returns>
        public async Task Publish(string publish_topic, string publish_msg)
        {
            if (mqttClient != null)
            {
                try
                {
                    await mqttClient.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(publish_topic).WithPayload(publish_msg).WithExactlyOnceQoS().Build());

                }
                catch (Exception err)
                {

                }
            }
        }
        //static public async Task Publish(IManagedMqttClient mqttClient_1, string publish_topic, string publish_msg)
        //{
        //    if (mqttClient_1 != null)
        //    {
        //        try
        //        {
        //            await mqttClient_1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(publish_topic).WithPayload(publish_msg).WithExactlyOnceQoS().Build());

        //        }
        //        catch (Exception err)
        //        {

        //        }
        //    }
        //}
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task StopAsync()
        {
            if (mqttClient != null)
            {
                await mqttClient.UnsubscribeAsync(new string[] { topic });
                await mqttClient.StopAsync();
            }
        }
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="x"></param>
        //private static void OnSubscriberConnected(MqttClientConnectedEventArgs x)
        //{
        //    var rec = x.AuthenticateResult.ResultCode.ToString();
        //    // label_State.Text = rec;
        //}
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="x"></param>
        //private static void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs x)
        //{
        //    //var rec = x.AuthenticateResult.ResultCode.ToString();
        //    //label_State.Text = rec;
        //}
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="x"></param>
        //private static void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
        //{
        //    var rec = x.ApplicationMessage.ConvertPayloadToString();
        //    // txt_Rec.Text = txt_Rec.Text + rec + System.Environment.NewLine;

        //}



    }
}
