#include "MiCASAKeys.h"
#include <nsMemory.h>
#include <nsStringAPI.h>

/* Implementation file */
NS_IMPL_ISUPPORTS1(MiCASAKeys, IMiCASAKeys)

MiCASAKeys::MiCASAKeys()
{
   m_bLibraryLoaded = FALSE;
   m_pCASAOpen = NULL;
   m_pCASAClose = NULL;
   m_pCASAWriteKey = NULL;
   m_pCASAReadKey = NULL;

   /* member initializers and constructor code */
   m_hCASALibrary = LoadLibrary("micasa.dll");

   if (m_hCASALibrary)
   {
      m_pCASAOpen = (PCASAOPEN)GetProcAddress(m_hCASALibrary, "miCASAOpenSecretStoreCache");
      m_pCASAClose = (PCASACLOSE)GetProcAddress(m_hCASALibrary, "miCASACloseSecretStoreCache");
      m_pCASAWriteKey = (PCASAWRITEKEY)GetProcAddress(m_hCASALibrary, "miCASAWriteKey");
      m_pCASAReadKey = (PCASAREADKEY)GetProcAddress(m_hCASALibrary, "miCASAReadKey");

      m_bLibraryLoaded = TRUE;
   }
}

MiCASAKeys::~MiCASAKeys()
{
   /* destructor code */
//   if (m_bLibraryLoaded == TRUE)
//   {
//      FreeLibrary(m_hCASALibrary);
//      m_bLibraryLoaded = FALSE;
//   }
}

/* PRInt32 miCASAWriteKey (in string secretId, in string key, in string value); */
//NS_IMETHODIMP MiCASAKeys::MiCASAWriteKey(const char *secretId, const char *key, const char *value, PRInt32 *_retval)

/* PRInt32 miCASAWriteKey (in AUTF8String secretId, in AUTF8String key, in AUTF8String value); */
NS_IMETHODIMP MiCASAKeys::MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval)
{

   if (m_bLibraryLoaded == TRUE)
   {
      nsresult             result;
      SSCS_KEYCHAIN_ID_T   sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
      SSCS_SECRET_ID_T     sharedId;
      SSCS_SECRETSTORE_T   ssId;
      HANDLE               context;

      ssId.version = NSSCS_VERSION_NUMBER;
      strncpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID, sizeof(ssId.ssName));

      result = NSSCS_E_SYSTEM_FAILURE;

      if (m_pCASAOpen)
      {
         context = (*m_pCASAOpen)(
                     &ssId,
                     0,
                     NULL);
   
   
         if (context)
         {
            sharedId.len = secretId.Length() + 1;
            strncpy((char *)sharedId.id, secretId.BeginReading(), sizeof(sharedId.id));
      
            if (m_pCASAWriteKey)
            {
               result = (*m_pCASAWriteKey)(
                         context,
                         0,
                         &sessionKeyChain,
                         &sharedId,
                         (unsigned char *)key.BeginReading(),
                         key.Length() + 1,
                         (unsigned char *)value.BeginReading(),
                         value.Length() + 1,
                         NULL,
                         NULL);
            }
   
            (*m_pCASAClose)(
               context,
               0,
               NULL);
         }
      }

      *_retval = result;
      return result;
   }
   else
   {
      return NSSCS_E_SERVICE_NOT_FOUND;
   }
}

/* PRInt32 miCASAReadKey (in string secretId, in string key, out string value); */
//NS_IMETHODIMP MiCASAKeys::MiCASAReadKey(const char *secretId, const char *key, char **value, PRInt32 *_retval)

/* PRInt32 miCASAReadKey (in AUTF8String secretId, in AUTF8String key, out AUTF8String value); */
NS_IMETHODIMP MiCASAKeys::MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval)
{

   if (m_bLibraryLoaded == TRUE)
   {
      nsresult             result;
      SSCS_KEYCHAIN_ID_T   sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
      SSCS_SECRET_ID_T     sharedId;
      SSCS_SECRETSTORE_T   ssId;
      uint32_t             bytesRequired;
      HANDLE               context;

      ssId.version = NSSCS_VERSION_NUMBER;
      strncpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID, sizeof(ssId.ssName));

      result = NSSCS_E_SYSTEM_FAILURE;

      if (m_pCASAOpen)
      {
         context = (*m_pCASAOpen)(
                     &ssId,
                     0,
                     NULL);
   
         if (context)
         {
            uint32_t      valueLength = 256;
            unsigned char tempValue[257];
   
            sharedId.len = secretId.Length() + 1;
            strncpy((char *)sharedId.id, secretId.BeginReading(), sizeof(sharedId.id));
      
            if (m_pCASAReadKey)
            {
               result = (*m_pCASAReadKey)(
                         context,
                         0,
                         &sessionKeyChain,
                         &sharedId,
                         (unsigned char *)key.BeginReading(),
                         key.Length() + 1,
                         tempValue,
                         &valueLength,
                         NULL,
                         &bytesRequired,
                         NULL);
      
               value.Assign((char *)tempValue, valueLength - 1);
            }
   
            (*m_pCASAClose)(
               context,
               0,
               NULL);
         }
      }

      *_retval = result;
      return result;
   }
   else
   {
      return NSSCS_E_SERVICE_NOT_FOUND;
   }
}