/***********************************************************************
 * 
 *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library 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
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 ***********************************************************************/

using System;
using System.Collections;

using System.Collections.Specialized;
using Novell.CASA.MiCasa.Common;
using Novell.CASA.MiCasa.Communication;

namespace Novell.CASA
{
	/// <summary>
	/// Summary description for Secret.
	/// </summary>
	public class Secret : MarshalByRefObject
	{
		internal IntPtr m_pHsc;
		private string m_keyChainID;
		private uint m_ssFlags;
		internal IntPtr m_secretHandle;
		private string m_secretID;		
		private string m_epPassword = null;
		private uint m_iCreateTime = 0;
		private uint m_iModifyTime = 0;
		private uint m_iAccessTime = 0;
		internal int m_type = 0;

		// holds name value pairs for this secret
		private System.Collections.Specialized.NameValueCollection m_nvc;
		private byte[] m_baValue = null;
		
		public static int SS_APP = 1;
		public static int SS_CREDSET = 2;
		public static int SS_BINARY = 4;


		// constructor
		internal Secret(
			IntPtr pHSC,
			string sKeyChainID, 
			uint iSSFlags, 
			IntPtr ptrHandle, 
			string sSecretID,
 			int iSecretType,
			string sEPPassword)
		{
			m_pHsc = pHSC;
			m_keyChainID = sKeyChainID;
			m_ssFlags = iSSFlags;
			m_secretHandle = ptrHandle;			
			m_secretID = sSecretID;			
			m_epPassword = sEPPassword;

			m_type = iSecretType;

			if (sSecretID.StartsWith("SS_CredSet"))
				m_type = Secret.SS_CREDSET;
			else if (sSecretID.StartsWith("SS_App"))
				m_type = Secret.SS_APP;
			else if (sSecretID.StartsWith("SS_Binary"))
				m_type = Secret.SS_BINARY;

			// create collection
			m_nvc = new System.Collections.Specialized.NameValueCollection();
			
		}
		
		// TO clean up SecretHandle		

		public string getID()
		{
			return m_secretID;
		}

		public void setKeyValuePair(string sKey, string sKeyValue)
		{
			if (m_type == Secret.SS_APP)
				m_nvc.Add(sKey, sKeyValue);
			else
				m_nvc.Set(sKey, sKeyValue);			
		}

		public byte[] getBinaryValue()
		{
			return m_baValue;
		}

		// used for binary secrets, throws exception if not
		public void setBinaryValue(byte[] baData)
		{
			// make sure this is a binary secret
			if (this.m_type == SS_BINARY)
			{
				m_baValue = baData;
			}
			else
			{
				throw new Exception();
			}
		}

		public string[] getKeyValues(string sKey)
		{
			return m_nvc.GetValues(sKey);
		}

		public string getKeyValue(string sKey)
		{
			return m_nvc.Get(sKey);
		}

		public int getSecretType()
		{
			return this.m_type;
		}

//		public string getSecretValue()
//		{	
//			// TODO  this is for a raw secret, just an ID and value
//			// should be only one key in the NameValueCollection
//		}

		public NameValueCollection getKeyValueCollection()
		{
			return m_nvc;
		}

		public void mergeKeyValueCollection(NameValueCollection nvc)
		{
			//if (m_nvc == null)
			m_nvc = nvc;						
		}
		
		public void setEnhancedProtectionPassword(string sEPPassword)
		{
			m_epPassword = sEPPassword;
		}

		internal string getEnhancedProtectionPassword()
		{
			return m_epPassword;
		}

		public bool isEnhancedProtected()
		{
			if (m_epPassword != null)
				return true;
			else
				return false;
		}

		public void removeKey(string sKey, uint ctxFlags)
		{
			//call the ndk to remove that one too.
			NativeCalls.removeKeyValue(this.m_secretHandle, sKey, m_nvc.Get(sKey), ctxFlags);
 					
			// remove from our collection
			m_nvc.Remove(sKey);
		}

		internal void setTimeStamps(uint uiCreated, uint uiModified, uint uiAccessed)
		{
			m_iCreateTime = uiCreated;
			m_iModifyTime = uiModified;
			m_iAccessTime = uiAccessed;
		}

		public uint getCreateTime()
		{
			return m_iCreateTime;
		}

		public uint getModifiedTime()
		{
			return m_iModifyTime;
		}

		public uint getAccessTime()
		{
			return m_iAccessTime;
		}

		public Hashtable GetLinkedKeys(string sKey)
		{
			Hashtable htLinkedKeys = (Hashtable)MiCasaRequestReply.Send(MiCasaRequestReply.VERB_GET_LINKED_KEYS,
				null,
				this.getID(),
				sKey,
				null);

			
			return htLinkedKeys;

		}
	}
}