﻿using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Threading.Tasks;
using System.Runtime.Serialization;
using CrmMonitoring.Common.Configuration;
using NLog;

namespace CrmMonitoring.Common.Scafolding
{
    public abstract class RemoteProbeReceiver<T> : RemoteProbe
    {
        public string Location { get; set; }

        public string ConnectionStringName { get; set; }

        public string TopicName { get; set; }

        public string MeassureName { get; set; }

        public string SubcriptionName { get; set; }

        private SubscriptionClient _client;
        public virtual SubscriptionClient AzureClient
        {
            get
            {
                if (_client == null)
                {
                    var connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;
                    var nsmgr = NamespaceManager.CreateFromConnectionString(connectionString);

                    if (!nsmgr.SubscriptionExists(TopicName, SubcriptionName))
                    {
                        nsmgr.CreateSubscription(TopicName, SubcriptionName, GetFilters());
                    }

                    _client = SubscriptionClient.CreateFromConnectionString(connectionString, TopicName, SubcriptionName);
                }

                return _client;
            }
        }

        protected override void RunTest()
        {
            try
            {
                var message = AzureClient.Receive();
                if (message != null)
                {
                    UpdateValues(message.GetBody<T>());

                    message.Complete();
                }
            }
            catch (MessagingException me)
            {
                if (me.IsTransient)
                {
                    logger.Warn(me);
                }
                else
                {
                    throw me;
                }
            }
        }

        protected virtual BrokeredMessage CreateMessage(object result)
        {
            return new BrokeredMessage(result);
        }

        protected virtual Filter GetFilters()
        {
            return new SqlFilter(string.Format("Location = '{0}' AND MeassureName = '{1}'", Location, MeassureName));
        }

        public override void LoadDefinition(RemoteProbeDefinition definiton)
        {
            this.Interval = definiton.Interval;
            this.ProbeName = definiton.ProbeName;
            this.Configuration = definiton.Configuration;
            this.Location = definiton.Location;
            this.ConnectionStringName = definiton.ConnectionStringName;
            this.TopicName = definiton.TopicName;
            this.SubcriptionName = definiton.SubcriptionName;
            this.MeassureName = definiton.MeassureName;
            this.MemoryLength = definiton.MemoryLength;
            this.Treshold = definiton.Treshold;
            this.logger = LogManager.GetLogger(ProbeName);

        }

        public override void LoadDefinition(ProbeDefinition definiton)
        {
            throw new ApplicationException("Remote Probe does not support ProbeDefinition use RemoteProbeDefinition instead");
        }

        protected abstract void UpdateValues(T value);


    }
}
