//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Data;
using System.Web.Mail;
using CommunityServer.Configuration;

namespace CommunityServer.Components
{
	/// <summary>
	/// Summary description for EmailTemplateProvider.
	/// </summary>
	public abstract class EmailQueueProvider
	{
		public static readonly string EmailQueueProviderName = "EmailQueueProvider";

		#region Instance

		private static EmailQueueProvider _defaultInstance = null;

		static EmailQueueProvider()
		{
			CreateDefaultCommonProvider();
		}

		/// <summary>
		/// Returns an instance of the user-specified data provider class.
		/// </summary>
		/// <returns>An instance of the user-specified data provider class.  This class must inherit the
		/// CommonDataProvider interface.</returns>
		public static EmailQueueProvider Instance() 
		{
			return _defaultInstance;
		}

		public static EmailQueueProvider Instance(Provider dataProvider) 
		{
			EmailQueueProvider provider = CSCache.Get(dataProvider.Name) as EmailQueueProvider;
			if(provider == null)
			{
				provider = DataProviders.Invoke(dataProvider) as EmailQueueProvider;
				CSCache.Max(dataProvider.Name,provider);
			}
			return provider;
		}

		/// <summary>
		/// Creates the Default CommonDataProvider
		/// </summary>
		private static void CreateDefaultCommonProvider()
		{
			// Get the names of the providers
			//
			CSConfiguration config = CSConfiguration.GetConfig();

			// Read the configuration specific information
			// for this provider
			//
			Provider sqlForumsProvider = (Provider) config.Providers[EmailQueueProviderName];

			// Read the connection string for this provider
			//
            
			_defaultInstance = DataProviders.CreateInstance(sqlForumsProvider) as EmailQueueProvider;
		}

		#endregion

		/// <summary>
		/// A method to add an email message to the email queue which will be processed later by a background thread
		/// which will actually send the email message, or this method can find a way to handle the sending immediately.
		/// </summary>
		/// <param name="message">The email message to send</param>
		public abstract void QueueEmail(MailMessage message);

		/// <summary>
		/// A method called by the framework to retrieve email messages from the email queue.
		/// </summary>
		/// <returns>An ArrayList of MailMessage(s) that will need to be sent.</returns>
		public abstract ArrayList DequeueEmail(int settingsID);

		/// <summary>
		/// A method to remove email messages from the email queue that were successfully sent.
		/// </summary>
		/// <param name="emailID">The EmailID (Guid) that was successfully sent.</param>
		public abstract void DeleteQueuedEmail(Guid emailID);

		/// <summary>
		/// A method to updated failed email messages in the email queue that were not sent.
		/// </summary>
		/// <param name="list">The list of EmailIDs (Guids) that were not sent.</param>
		/// <param name="failureInterval">The number of minutes before attempting again.  This is scaled against the number of tries.</param>
		public abstract void QueueSendingFailure (ArrayList list, int failureInterval, int maxNumberOfTries);

		#region Populate Methods

		// *********************************************************************
		//
		//  PopulateEmailFromIDataReader
		//
		/// <summary>
		/// This private method accepts a datareader and attempts to create and
		/// populate a EmailTempalte class instance which is returned to the caller.
		/// </summary>
		//
		// ********************************************************************/
		public static EmailTemplate PopulateEmailFromIDataReader(IDataReader reader) 
		{
			EmailTemplate email = new EmailTemplate();

			email.EmailID       = (Guid) reader["EmailID"];
			email.Priority      = (MailPriority) (int) reader["emailPriority"];
			email.BodyFormat    = (MailFormat) (int) reader["emailBodyFormat"];
			email.Subject       = (string) reader["emailSubject"];
			email.To            = (string) reader["emailTo"];
			email.From          = (string) reader["emailFrom"];
			email.Body          = (string) reader["emailBody"];
			email.NumberOfTries = (int) reader["numberOfTries"];

			if (reader["emailCc"] != DBNull.Value)
				email.Cc = (string) reader["emailCc"];

			if (reader["emailBcc"] != DBNull.Value)
				email.Bcc = (string) reader["emailBcc"];

			return email;
		}

		#endregion

	}
}
