// WebDavConfig.cs created with MonoDevelop
// User: klose at 17:32 04.08.2012
// CVS release: $Id$
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2011  Thomas Klose, Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Net.NetworkInformation;
using System.Net;
using System.Threading;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
using System.Xml.Serialization;

using net.kvdb.webdav;


namespace Hiperscan.GUI
{
	public class WebDavConfig
	{
		public static readonly string Server = "pdc.hiperscan.com";
		public static readonly string User = "quickstep";
		public static readonly string Pass = "w68VQtJj";
		public static readonly string BasePath = "/home/quickstep/";
		
		public static void Read()
		{
			// FIXME: disabled due to problems under Mono 4.x
			return;

			if (!Ping())
				return;

			Console.WriteLine("WebDAV server reachable: {0}", Server);

			WebDAVClient c = new WebDAVClient();
			c.Server = "http://" + Server;
			c.User = User;
			c.Pass = Pass;
			c.BasePath = BasePath;
			
			List<string> files = null;
			AutoResetEvent auto_reset_event = new AutoResetEvent(false);
			c.ListComplete += delegate(List<string> _files, int _status)
			{
				files = _files;
				auto_reset_event.Set(); 
			};
			c.DownloadComplete += delegate { auto_reset_event.Set(); };

			AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e) {
				if (e.ExceptionObject is System.Net.WebException)
				{
					Console.WriteLine(e.ExceptionObject.ToString());
					auto_reset_event.Set();
				}
			};

			c.List();
			auto_reset_event.WaitOne();
			
			Console.WriteLine("Synchronize configuration ...");

			if (!Directory.Exists(UserInterface.ConfigDirPath))
				Directory.CreateDirectory(UserInterface.ConfigDirPath);

			DateTime timestamp = DateTime.MinValue;
			if (File.Exists(Path.Combine(UserInterface.ConfigDirPath, UserInterface.USER_CONFIG_FILE_NAME)))
			    timestamp = File.GetLastAccessTime(Path.Combine(UserInterface.ConfigDirPath, UserInterface.USER_CONFIG_FILE_NAME));

			foreach (string file in files)
			{
				if (file == Environment.UserName + ".xml")
				{
					string tmp_file = Path.GetTempFileName();
					auto_reset_event.Reset();
					c.Download(file, tmp_file);
					auto_reset_event.WaitOne();
					WebDAVConfigData data = WebDAVConfigData.ReadFromFile(tmp_file);
					File.Delete(tmp_file);
					
					if (data.Timestamp <= timestamp)
					{
						Console.WriteLine("Local config is more up to date.");
						return;
					}
					
					for (int ix=0; ix < data.Files.Count; ++ix)
					{
						if (Path.GetFileName(data.Files[ix]).EndsWith(".config") == true)
							continue;
						File.WriteAllText(Path.Combine(UserInterface.ConfigDirPath, data.Files[ix]), data.Contents[ix]);
					}
					break;
				}
			}
			
			Console.WriteLine("Done.");
		}
		
		public static void Write()
		{
			// FIXME: disabled due to problems under Mono 4.x
			return;

			if (!Ping())
				return;
			
			Console.WriteLine("WebDAV server reachable: {0}", Server);
			
			WebDAVClient c = new WebDAVClient();
			c.Server = "http://" + Server;
			c.User = User;
			c.Pass = Pass;
			c.BasePath = BasePath;
			
			AutoResetEvent auto_reset_event = new AutoResetEvent(false);
			c.UploadComplete += delegate {
				auto_reset_event.Set(); 
			};
			
			AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e) {
				if (e.ExceptionObject is System.Net.WebException)
				{
					Console.WriteLine(e.ExceptionObject.ToString());
					auto_reset_event.Set();
				}
			};

			File.WriteAllText(Path.Combine(UserInterface.ConfigDirPath, "timestamp"), DateTime.Now.Ticks.ToString());

			Console.WriteLine("Synchronize configuration ...");

			WebDAVConfigData data = new WebDAVConfigData();
			foreach (string file in Directory.GetFiles(UserInterface.ConfigDirPath))
			{
				if (Path.GetFileName(file).EndsWith(".config") == true)
					continue;
				data.Files.Add(Path.GetFileName(file));
				data.Contents.Add(File.ReadAllText(file));
			}
			
			string tmp_file = Path.GetTempFileName();
			data.WriteToFile(tmp_file);

			c.Upload(tmp_file, Environment.UserName + ".xml");
			auto_reset_event.WaitOne(1000);
			File.Delete(tmp_file);
			
			Console.WriteLine("Done.");
		}
		
		private static bool Ping()
		{
			return Hiperscan.GUI.Ping.Send(Server);
		}
	}
	
	[Serializable()]
	public class WebDAVConfigData
	{
		public DateTime     Timestamp { get; set; }
		public List<string> Files     { get; set; }
		public List<string> Contents  { get; set; }
		
		public WebDAVConfigData()
		{
			Timestamp = DateTime.Now;
			Files = new List<string>();
			Contents = new List<string>();
		}
		
		public static WebDAVConfigData ReadFromFile(string fname)
		{
			using (Stream stream = new FileStream(fname, FileMode.Open))
			{
				using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8))
				{
					XmlSerializer serializer = new XmlSerializer(typeof(WebDAVConfigData));
					WebDAVConfigData config = (WebDAVConfigData)serializer.Deserialize(reader);
					
					if (config == null)
						throw new Exception("Error while deserialization.");
					
					return config;
				}
			}
		}

		public void WriteToFile(string fname)
		{
			using (Stream stream = new FileStream(fname, FileMode.Create))
			{
				using (StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.UTF8))
				{
					XmlSerializer serializer = new XmlSerializer(typeof(WebDAVConfigData));
					serializer.Serialize(writer, this);
				}
			}
		}
	}
}