/// <summary>
        /// Sends a daily score notification to the configured recipient if automated notifications are enabled and we're below a threshold score
        /// The caller must handle exceptions
        /// </summary>
        public void SendQuarterlyScoreAlerts()
        {
            //Gatekeeper #1: We will only try to send notifications if they're turned on and ratings exist
            var sendNotifications = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendDailyNotifications) ?? "False");
            var ratingsExist      = ReportingService.LookingGlassHasRun();

            if (!sendNotifications || !ratingsExist)
            {
                return;
            }

            //Gatekeeper #2: If there's no one to send to, don't bother
            var recipients = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsQuarterlyScoreAlerts);

            if (string.IsNullOrEmpty(recipients))
            {
                return;
            }

            var scores = ReportingService.GetOverallScores();

            //Gatekeeper #3: Only send a notice if we're below the threshold or we were last time
            var defaultThreshold = new QualityIndicatorConfigurationService(this.configurationRepository).GetIndictatorConfiguration();
            int threshold;

            int.TryParse(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsThresholdQuarterlyScore) ?? defaultThreshold.PassScore.ToString(), out threshold);
            var belowThreshold     = scores.QuarterlyScore < threshold;
            var belowThresholdLast = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.LastQuarterlyScoreBelowThreshold) ?? "False");

            if (!belowThreshold && !belowThresholdLast)
            {
                return;
            }
            this.configurationRepository.SetConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.LastQuarterlyScoreBelowThreshold, belowThreshold.ToString());

            //Prepare and send the notice
            var settings     = this.GetSmtpConfiguration();
            var instanceName = Database.ReadInstanceName();
            var message      = BuildQuarterlyScoreAlert(scores, instanceName, belowThreshold);
            var client       = this.smtpClientFactory.CreateSmtpClient(settings);
            var mailMessage  = BuildMailMessage(settings, recipients, "Performance Dashboard - Quarterly Score Alert", message);

            client.Send(mailMessage);
        }
        public PerformanceDashboardConfigurationSettings GetConfiguration()
        {
            var config = new PerformanceDashboardConfigurationSettings
            {
                BackupDbccSettings   = new BackupDbccMonitoringConfigurationSettings(),
                NotificationSettings = new NotificationSettings()
            };

            var qualityLevels = new QualityIndicatorConfigurationService(this.configurationRepository).GetIndictatorConfiguration();

            // Populate last modified by
            config.LastModifiedBy = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.ConfigurationEditedBy) ?? string.Empty;

            // Read DBCC settings
            config.BackupDbccSettings.UseViewBasedMonitoring    = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.UseDbccViewMonitoring) ?? "False");
            config.BackupDbccSettings.UseCommandBasedMonitoring = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.UseDbccCommandMonitoring) ?? "False");
            config.BackupDbccSettings.ShowInvariantHistory      = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.ShowInvariantBackupDbccHistory) ?? "False");

            // Read enabled settings
            config.NotificationSettings.BackupDBCCAlert.Enabled          = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendBackupDbccNotifications) ?? "False");
            config.NotificationSettings.QuarterlyScoreStatus.Enabled     = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendWeeklyNotifications) ?? "False");
            config.NotificationSettings.QuarterlyScoreAlert.Enabled      = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendDailyNotifications) ?? "False");
            config.NotificationSettings.WeeklyScoreAlert.Enabled         = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendHourlyNotifications) ?? "False");
            config.NotificationSettings.ConfigurationChangeAlert.Enabled = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendConfigurationChangeNotifications) ?? "False");
            config.NotificationSettings.SystemLoadForecast.Enabled       = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendSystemLoadForecast) ?? "False");
            config.NotificationSettings.UserExperienceForecast.Enabled   = Convert.ToBoolean(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.SendUserExperienceForecast) ?? "False");

            // Read recipient settings
            config.NotificationSettings.WeeklyScoreAlert.Recipients         = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsWeeklyScoreAlerts) ?? string.Empty;
            config.NotificationSettings.SystemLoadForecast.Recipients       = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsSystemLoadForecast) ?? string.Empty;
            config.NotificationSettings.UserExperienceForecast.Recipients   = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsUserExperienceForecast) ?? string.Empty;
            config.NotificationSettings.QuarterlyScoreAlert.Recipients      = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsQuarterlyScoreAlerts) ?? string.Empty;
            config.NotificationSettings.QuarterlyScoreStatus.Recipients     = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsQuarterlyScoreStatus) ?? string.Empty;
            config.NotificationSettings.BackupDBCCAlert.Recipients          = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsBackupDBCCAlerts) ?? string.Empty;
            config.NotificationSettings.ConfigurationChangeAlert.Recipients = this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsRecipientsConfigurationChangeAlerts) ?? string.Empty;

            // Read threshold values
            config.NotificationSettings.WeeklyScoreAlert.Threshold       = int.Parse(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsThresholdWeeklyScore) ?? qualityLevels.PassScore.ToString());
            config.NotificationSettings.QuarterlyScoreAlert.Threshold    = int.Parse(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsThresholdQuarterlyScore) ?? qualityLevels.PassScore.ToString());
            config.NotificationSettings.SystemLoadForecast.Threshold     = int.Parse(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsThresholdSystemLoadScore) ?? qualityLevels.PassScore.ToString());
            config.NotificationSettings.UserExperienceForecast.Threshold = int.Parse(this.configurationRepository.ReadConfigurationValue(ConfigurationKeys.Section, ConfigurationKeys.NotificationsThresholdUserExperienceScore) ?? qualityLevels.PassScore.ToString());

            // Read process control frequencies
            var processes = this.processControlRepository.ReadAll();
            var p         = processes.FirstOrDefault(x => x.Id == ProcessControlId.RecoverabilityIntegrityAlerts);

            config.NotificationSettings.BackupDBCCAlert.Frequency = p != null
                                ? p.Frequency.GetValueOrDefault(1440)
                                : 1440;

            p = processes.FirstOrDefault(x => x.Id == ProcessControlId.QuarterlyScoreAlerts);
            config.NotificationSettings.QuarterlyScoreAlert.Frequency = p != null
                                ? p.Frequency.GetValueOrDefault(1440)
                                : 1440;

            p = processes.FirstOrDefault(x => x.Id == ProcessControlId.QuarterlyScoreStatus);
            config.NotificationSettings.QuarterlyScoreStatus.Frequency = p != null
                                ? p.Frequency.GetValueOrDefault(10080)
                                : 10080;

            p = processes.FirstOrDefault(x => x.Id == ProcessControlId.InfrastructurePerformanceForecast);
            config.NotificationSettings.SystemLoadForecast.Frequency = p != null
                                ? p.Frequency.GetValueOrDefault(60)
                                : 60;

            p = processes.FirstOrDefault(x => x.Id == ProcessControlId.UserExperienceForecast);
            config.NotificationSettings.UserExperienceForecast.Frequency = p != null
                                ? p.Frequency.GetValueOrDefault(60)
                                : 60;

            p = processes.FirstOrDefault(x => x.Id == ProcessControlId.WeeklyScoreAlerts);
            config.NotificationSettings.WeeklyScoreAlert.Frequency = p != null
                                ? p.Frequency.GetValueOrDefault(60)
                                : 60;

            return(config);
        }