// PwdBackend.cs
//
//  Copyright (C) 2009-2010 Christian Eide
//
// 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 2 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//

using System;
using System.Collections;
using System.Collections.Generic;
#if HAVE_GNOME_KEYRING
using Gnome.Keyring;
#endif

namespace bareFTP.Preferences
{
	
	public class PwdBackend
	{
		
		const string RootPath = "bareftp";
		string keyring = string.Empty;
		public PwdBackend()
		{

		}
		
		public void CheckKeyring()
		{
#if HAVE_GNOME_KEYRING			
			if(!Ring.Available)
				throw new Exception("Gnome Keyring not available");
			
			
			keyring = Ring.GetDefaultKeyring();
			if(string.IsNullOrEmpty(keyring))
				keyring = "login";
#endif
		}
		
		public string GetPwd(int keyid)
		{
#if HAVE_GNOME_KEYRING
			if(!Ring.Available)
				throw new Exception("Gnome Keyring not available");
			
			if(keyid > -1)
			{
				try
				{
					ItemData item = Ring.GetItemInfo(keyring, keyid);
					return item.Secret;
				}
				catch (KeyringException) {
					return string.Empty;
				}
			}
			return string.Empty;
#else
			return string.Empty;
#endif
		}
		
		public int SetPwd(string user, string host, int protocol, string port, string passwd, bool isnew)
		{
#if HAVE_GNOME_KEYRING
			
			if (!Ring.Available) {
				throw new Exception("Gnome Keyring not available");
			}
			
			string _protocol = "ftp";
			if(protocol == 3)
				_protocol = "sftp";
			
			Hashtable hash = new Hashtable();
			hash["user"] = user;
			hash["server"] = host;
			hash["protocol"] = _protocol;
			hash["obj"] = "bareftp";
			if(!string.IsNullOrEmpty(port))
				hash["port"] = Convert.ToInt32(port);
			
			
			int keyid = -1;
			
			try {
				keyid = Ring.CreateItem(keyring, ItemType.NetworkPassword, 
				                "bareftp:" + user + "@" + host, hash, passwd, isnew);
			} catch (KeyringException) {
				return -1;
			}

			return keyid;
#else
			return -1;
#endif
		}
		
		public bool HasGnomeKeyring
		{
			get
			{ 
#if HAVE_GNOME_KEYRING
				
				try { return Ring.Available; }
				catch { return false; }
#else
				return false;
#endif
			}
		}
		
		public void CleanUpItems()
		{
#if HAVE_GNOME_KEYRING
			if(!Ring.Available)
				throw new Exception("Gnome Keyring not available");
			
			try
			{
				List<int> ids = new List<int>();    
        		
				foreach (int id in Ring.ListItemIDs (keyring)) {
					Hashtable tbl = Ring.GetItemAttributes(keyring, id);
					if(tbl["obj"] != null && tbl["obj"].ToString() == "bareftp")
						ids.Add(id);
				}
				foreach(int id in ids)
				{
					Ring.DeleteItem(keyring, id);	
				}	
			} catch (KeyringException) {
				
			}
#endif
		}
		
		public bool DeletePassword(int keyid)
		{
#if HAVE_GNOME_KEYRING
			if(!Ring.Available)
				throw new Exception("Gnome Keyring not available");

			try {
				ItemData data = Ring.GetItemInfo(keyring, keyid);
				if(data != null)
				{
					
					if(data.ItemID == keyid)
					{
						Ring.DeleteItem(keyring, data.ItemID);
						return true;
					}
				}
				
			} catch (KeyringException) {
				return false;
			}
#endif
			return false;
		}
	}
	
	public class KeyringException : Exception
	{
		public KeyringException(string msg) : base(msg) {}
	}
}
