/// <summary>
        /// Called by the WCF service when an attempt is made to notify everyone of a notification event
        /// Tracks an outgoing SNC notification attempt to subscribers in the database
        /// </summary>
        /// <param name="notificationEvent"></param>
        public int CreateNotification(string publisher, string notificationEvent, string message)
        {
            // Insert a notification record
            using (var db = new XanoSNCEntities())
            {
                // Lookup the notification event by name
                var notificationEventDB = (from ne in db.xNotificationEvents
                                           where ne.Name == notificationEvent
                                           select ne).SingleOrDefault();
                if (notificationEventDB == null)
                    throw new Exception("Notification by name: " + notificationEvent + " does not exist");

                var publisherDB = (from p in db.xPublishers
                                           where p.Name == publisher
                                           select p).SingleOrDefault();
                if (publisherDB == null)
                    throw new Exception("Publisher by name: " + publisher + " does not exist");

                var notification = new xNotification()
                {
                    NotificationEventId = notificationEventDB.Id,
                    PublisherId = publisherDB.Id,
                    Message = message,
                    CreatedDate = DateTime.Now,
                };

                db.xNotifications.Add(notification);

                db.SaveChanges();

                return notification.Id;
            }
        }
        /// <summary>
        /// Stores a new notification type in the database
        /// </summary>
        /// <param name="publisher"></param>
        /// <param name="notificationEvent"></param>
        /// <param name="jsonSchema">json Schema for the notification message that will be sent to subscribers</param>
        /// <returns>A token that the publisher must use in subsequent calls to NotifySubscribers</returns>
        public string CreateNotificationEvent(string publisher, string notificationEvent, string jsonSchema)
        {
            using (var db = new XanoSNCEntities())
            {
                var publisherId = 0;
                var xPublisher = (from p in db.xPublishers
                                  where p.Name == publisher
                                  select p).SingleOrDefault();
                if (xPublisher == null)
                {
                    var newPublisher = new xPublisher()
                    {
                        Name = publisher,
                        CreatedDate = DateTime.Now
                    };
                    db.xPublishers.Add(newPublisher);
                    publisherId = newPublisher.Id;
                }
                else
                {
                    publisherId = xPublisher.Id;
                }

                var token = Guid.NewGuid().ToString();

                var xNotificationEvent = (from ne in db.xNotificationEvents
                                  where ne.Name == notificationEvent
                                  select ne).SingleOrDefault();
                if (xNotificationEvent == null)
                {
                    db.xNotificationEvents.Add(new xNotificationEvent()
                    {
                        Name = notificationEvent,
                        PublisherId = publisherId,
                        JsonSchema = jsonSchema,
                        Token = token,
                        CreatedDate = DateTime.Now
                    });
                }
                else
                {
                    throw new Exception("Notification: " + notificationEvent + " already exists.");
                }

                db.SaveChanges();

                return token;
            }
        }
 public void UpdateSubscriptionNotificationWithError(int subscriptionNotificationId, string errorMessage)
 {
     using (var db = new XanoSNCEntities())
     {
         var xSubscriptionNotification = (from s in db.xSubscriptionNotifications
                                          where s.Id == subscriptionNotificationId
                                          select s).Single();
         xSubscriptionNotification.NotificationError = errorMessage;
         db.SaveChanges();
     }
 }
 /// <summary>
 /// Updates the Json schema associated with an existing notification event defined by the token
 /// </summary>
 /// <param name="token"></param>
 /// <param name="jsonSchemaString"></param>
 public void UpdateNotificationEventJsonSchema(
     string token,
     string jsonSchemaString)
 {
     using (var db = new XanoSNCEntities())
     {
         var notificationEvent = (from ne in db.xNotificationEvents
                                 where ne.Token == token
                                 select ne).SingleOrDefault();
         if (notificationEvent != null)
         {
             throw new Exception("No notification event found with token: " + token);
         }
         else
         {
             notificationEvent.JsonSchema = jsonSchemaString;
             db.SaveChanges();
         }
     }
 }
        /// <summary>
        /// Removes a service subscription to a notification in the database
        /// </summary>
        /// <param name="subscriber"></param>
        /// <param name="notificationEvent"></param>
        /// <param name="token">A token issued by the subscribe method</param>
        public void Unsubscribe(string subscriber, string notificationEvent, string token)
        {
            using (var db = new XanoSNCEntities())
            {
                var xNotificationEvent = (from ne in db.xNotificationEvents
                                          where ne.Name == notificationEvent
                                          select ne).SingleOrDefault();
                if (xNotificationEvent == null)
                {
                    throw new Exception("Notification event with name: " + notificationEvent + " has not been published.");
                }

                var xSubscriber = (from s in db.xSubscribers
                                   where s.Name == subscriber
                                   select s).SingleOrDefault();
                if (xSubscriber == null)
                {
                    throw new Exception("No subscriber with name: " + subscriber + " found.");
                }

                var xSubscriptionDB = (from sc in db.xSubscriptions
                                       join sb in db.xSubscribers on sc.SubscriberId equals sb.Id
                                       join ne in db.xNotificationEvents on sc.NotificationEventId equals ne.Id
                                       where ne.Name == notificationEvent && sb.Name == subscriber && sc.Token == token
                                       select new
                                       {
                                           SubscriberName = sb.Name,
                                           NotificationEvent = ne.Name,
                                           NotificationEventId = ne.Id,
                                           SubscriberId = sb.Id,
                                           SubscriptionId = sc.Id
                                       }).SingleOrDefault();
                if (xSubscriptionDB == null)
                {
                    throw new Exception("Subscription for subscriber " + subscriber + " for notification event " + notificationEvent + " not found with token " + token);
                }
                else
                {
                    var subscriptionDB = (from sc in db.xSubscriptions
                                          where sc.Id == xSubscriptionDB.SubscriptionId
                                          select sc).SingleOrDefault();
                    // Delete the subscription
                    db.xSubscriptions.Remove(subscriptionDB);
                    db.SaveChanges();
                }
            }
        }
        /// <summary>
        /// Stores a service subscription to a notification in the database
        /// </summary>
        /// <param name="subscriber"></param>
        /// <param name="notificationEvent"></param>
        /// <param name="notifyUrl"></param>
        /// <returns>A token that must be used when unsubscribing</returns>
        public string Subscribe(string subscriber, string notificationEvent, string emailAddress, string notifyUrl)
        {
            using (var db = new XanoSNCEntities())
            {
                var token = Guid.NewGuid().ToString();
                var xNotificationEvent = (from ne in db.xNotificationEvents
                                          where ne.Name == notificationEvent
                                          select ne).SingleOrDefault();
                if (xNotificationEvent == null)
                {
                    throw new Exception("Notification event with name: " + notificationEvent + " has not been published.");
                }

                var subscriberId = 0;
                var xSubscriber = (from s in db.xSubscribers
                                  where s.Name == subscriber
                                  select s).SingleOrDefault();
                if (xSubscriber == null)
                {
                    var newSubscriber = new xSubscriber()
                    {
                        Name = subscriber,
                        CreatedDate = DateTime.Now
                    };
                    db.xSubscribers.Add(newSubscriber);
                    subscriberId = newSubscriber.Id;
                }
                else
                {
                    subscriberId = xSubscriber.Id;
                }

                var xSubscriptionDB = (from sc in db.xSubscriptions
                                     join sb in db.xSubscribers on sc.SubscriberId equals sb.Id
                                     join ne in db.xNotificationEvents on sc.NotificationEventId equals ne.Id
                                     where ne.Name == notificationEvent && sb.Name == subscriber
                                     select new
                                     {
                                         SubscriberName = sb.Name,
                                         NotificationEvent = ne.Name,
                                         NotificationEventId = ne.Id,
                                         SubscriberId = sb.Id
                                     }).SingleOrDefault();
                if (xSubscriptionDB == null)
                {
                    db.xSubscriptions.Add(new xSubscription()
                    {
                        NotificationEventId = xNotificationEvent.Id,
                        SubscriberId = subscriberId,
                        NotifyURL = notifyUrl,
                        Token = token,
                        EmailAddress = emailAddress,
                        CreatedDate = DateTime.Now
                    });
                }
                else
                {
                    throw new Exception("Subscription: " + notificationEvent + " already exists.");
                }

                db.SaveChanges();

                return token;
            }
        }
        /// <summary>
        /// Called by the WCF service for each subscriber that we attempted to called
        /// </summary>
        /// <param name="notificationId">Id of the notification record</param>
        /// <param name="subscriber">Subscriber we attempted to contact</param>
        /// <param name="errorMessage">If an error occurred, this will be a non-null string with the message</param>
        public void CreateSubscriptionNotification(int notificationId, string subscriber, string errorMessage)
        {
            // Find the subscription id by subscriber name and notification event name
            // We need it to create a list of records for each subscriber that we attemped to contact
            using (var db = new XanoSNCEntities())
            {
                var subscriptionDB = (from sb in db.xSubscriptions
                                      join sc in db.xSubscribers on sb.SubscriberId equals sc.Id
                                      select sb).SingleOrDefault();

                if (subscriptionDB == null)
                    throw new Exception("Subscription does not exist!");

                var subscriptionNotification = new xSubscriptionNotification()
                {
                    CreatedDate = DateTime.Now,
                    NotificationError = errorMessage,
                    SubscriptionId = subscriptionDB.Id,
                };

                db.xSubscriptionNotifications.Add(subscriptionNotification);
                db.SaveChanges();
            }
        }
        public int CreateSubscriptionNotification(int notificationId, string subscriber)
        {
            using (var db = new XanoSNCEntities())
            {
                var xSubscriber = (from s in db.xSubscribers
                                   where s.Name == subscriber
                                   select s).SingleOrDefault();
                if (xSubscriber == null)
                {
                    throw new Exception("Subscriber with name: " + subscriber + " does not exist.");
                }

                var subscriptionNotification = new xSubscriptionNotification()
                {
                    NotificationId = notificationId,
                    SubscriptionId = xSubscriber.Id,
                    CreatedDate = DateTime.Now
                };

                db.xSubscriptionNotifications.Add(subscriptionNotification);

                db.SaveChanges();

                return subscriptionNotification.Id;
            }
        }