using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using Quartz;

namespace CharterDotCom.Common.Quartz
{
	/// <summary>
	/// 
	/// </summary>
	public static class StringExtensions
	{
		/// <summary>
		/// Rights the specified STR.
		/// </summary>
		/// <param name="sValue">The s value.</param>
		/// <param name="iMaxLength">Length of the i max.</param>
		/// <returns></returns>
		public static string Right(this string sValue, int iMaxLength)
		{
			//Check if the value is valid
			if (string.IsNullOrEmpty(sValue))
			{
				//Set valid empty string as string could be null
				sValue = string.Empty;
			}
			else if (sValue.Length > iMaxLength)
			{
				//Make the string no longer than the max length
				sValue = sValue.Substring(sValue.Length - iMaxLength, iMaxLength);
			}

			//Return the string
			return sValue;
		}
	}
	
	public class MyJob : IJob
	{
		/// <summary>
		/// The transfer dir
		/// </summary>
		protected string transferDir = @"C:\temp\logs";

		/// <summary>
		/// The archive dir
		/// </summary>
		protected string archiveDir = @"C:\temp\logs\archive";

		protected StringBuilder sbLogFileText;

		/// <summary>
		/// FTPs the file.
		/// </summary>
		/// <param name="fileInfo">The file info.</param>
		protected void FtpFile(FileInfo fileInfo)
		{
			try
			{
				sbLogFileText.AppendLine(string.Format("    Start Transfer {0}...", fileInfo.FullName));

				// Get the object used to communicate with the server.
				var request = (FtpWebRequest)WebRequest.Create(new Uri(@"ftp://" + "localhost" + @"/" + fileInfo.Name));
				request.Method = WebRequestMethods.Ftp.UploadFile;

				// FTP site credentials
				request.Credentials = new NetworkCredential("sal", @"V.{lJV}wy+%]");

				// Copy the contents of the file to the request stream.
				var sourceStream = new StreamReader(fileInfo.FullName);
				var fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
				sourceStream.Close();
				request.ContentLength = fileContents.Length;

				using (var requestStream = request.GetRequestStream())
				{
					requestStream.Write(fileContents, 0, fileContents.Length);
				}

				var response = (FtpWebResponse)request.GetResponse();

				var statusCode = (int)response.StatusCode;
				var statusDesc = response.StatusDescription;
				response.Close();

				sbLogFileText.AppendLine(string.Format("    Upload File Complete, status code {0}: desc: {1}", statusCode, statusDesc));

				fileInfo.MoveTo(Path.Combine(archiveDir, string.Format("{0}.{1}", fileInfo.Name, DateTime.Now.ToString("yyyyMMdd-Hmmss"))));
			}
			catch (Exception e)
			{
				sbLogFileText.AppendLine(string.Format("    Error in FtpFile: {0}", e.Message));
			}
		}

		/// <summary>
		/// FTPs the files.
		/// </summary>
		private void FtpFiles()
		{
			var filesToTransfer = Directory.GetFiles(transferDir, "*.*");

			sbLogFileText.AppendLine("--- Transfer Files: ---");

			foreach (var name in filesToTransfer)
			{
				var fileInfo = new FileInfo(Path.Combine(transferDir, name));
				sbLogFileText.AppendLine(fileInfo.FullName);
			}

			sbLogFileText.AppendLine("--- Starting to Transfer Files ---");
			var excludeDate = DateTime.Now.ToString("yyyy-MM-dd");
			foreach (var name in filesToTransfer)
			{
				var fileInfo = new FileInfo(Path.Combine(transferDir, name));
				
				if (!string.Equals(excludeDate, Path.GetFileNameWithoutExtension(fileInfo.Name).Right(10), StringComparison.InvariantCultureIgnoreCase))
				{
					sbLogFileText.AppendLine("    transferring: {0}", fileInfo.FullName);
					FtpFile(fileInfo);
				}
				else
				{
					sbLogFileText.AppendLine("    skipping: {0}", fileInfo.FullName);
				}
				sbLogFileText.AppendLine();
			}
			sbLogFileText.AppendLine("--- Done Transfering Files ---");
		}

		/// <summary>
		/// Called by the <see cref="IScheduler" /> when a <see cref="ITrigger" />
		/// fires that is associated with the <see cref="IJob" />.
		/// </summary>
		/// <remarks>
		/// The implementation may wish to set a  result object on the 
		/// JobExecutionContext before this method exits.  The result itself
		/// is meaningless to Quartz, but may be informative to 
		/// <see cref="IJobListener" />s or 
		/// <see cref="ITriggerListener" />s that are watching the job's 
		/// execution.
		/// </remarks>
		/// <param name="context">The execution context.</param>
		public void Execute(IJobExecutionContext context)
		{
			sbLogFileText = new StringBuilder();

			sbLogFileText.AppendLine("Quartz Job Running...");
			FtpFiles();
			sbLogFileText.AppendLine("Quartz Job finished.");
			CharterDotCom.Common.Logging.Logger.QuartzLog(sbLogFileText.ToString());
		}
	}
}
