/***********************************************************************
 * 
 *  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.
 * 
 ***********************************************************************/


#include "sscs_cache.h"
#include <wchar.h>
#include <assert.h>

#define MAX_ID_LIST_BUF 4*1024
#define MAX_SECRET_VAL_LEN 1024
#define MAX_RETURNED_IDS 10

void enumerateIDs(SSCS_SECRETSTORE_HANDLE_T *ssHandle,int type,
                  SSCS_KEYCHAIN_ID_T *keychainID)
{
	SSCS_KEYCHAIN_ID_LIST_T kcIDList;
	SSCS_SECRET_ID_LIST_T secretIDList;
        uint32_t ssFlags = 0;
	int retVal,i=0;
	
	if(type == 0) //keychains
	{
		printf("Enumerate keychains\n----------------------\n");
		kcIDList.keyChainIDList = (SSCS_KEYCHAIN_ID_T *)malloc(
                       sizeof(SSCS_KEYCHAIN_ID_T) * MAX_RETURNED_IDS );
                assert(kcIDList.keyChainIDList);

                kcIDList.returnedIDs = MAX_RETURNED_IDS;
		retVal = sscs_CacheEnumerateKeychainIDs(ssHandle, ssFlags,NULL, &kcIDList,NULL);
		if(retVal != 0)
		{
			printf("sscs_CacheEnumerateKeychainIDs failed: %d\n",retVal);
		}

                for( i = 0 ; i < kcIDList.returnedIDs; i++ )
                {
		    printf("%s\n",kcIDList.keyChainIDList[i].keychainID);
                }

		free(kcIDList.keyChainIDList);
	}
	else //secrets
	{
		printf("Enumerate secrets\n-----------------\n");
		secretIDList.secIDList = (SSCS_SECRET_ID_T*)malloc(
                     sizeof(SSCS_SECRET_ID_T)* MAX_RETURNED_IDS);
                assert(secretIDList.secIDList);

                secretIDList.returnedIDs = MAX_RETURNED_IDS;
		retVal = sscs_CacheEnumerateSecretIDs(ssHandle, ssFlags, keychainID, NULL, &secretIDList, NULL);
		if(retVal != 0)
		{
			printf("sscs_CacheEnumerateSecretIDs failed: %d\n",retVal);
		}

                for( i = 0 ; i < secretIDList.returnedIDs; i++ )
                {
                    printf("%s\n",secretIDList.secIDList[i].id);
                }

                free(secretIDList.secIDList);

	}
        printf("---------------------------------\n");
}


int main(int argc, char** argv)
{
        int n = 0,z=0;
	SSCS_SECRETSTORE_T secID;
	SSCS_SECRETSTORE_HANDLE_T *ssHandle = NULL;
	uint32_t bytesRequired;
        wchar_t *testssName;
        unsigned char testssNameUTF[1024];
        wchar_t *testkcId;
        unsigned char testkcIdUTF[1024];
        wchar_t *testsecretId;
        unsigned char testsecretIdUTF[1024];
        wchar_t **wptr = NULL;

	uint32_t ssFlags = 0;
	int retVal = 0;
	int i;
	SSCS_SECRET_T mySecret;
	SSCS_PASSWORD_T epPassword = {0,0,""};
        SSCS_SECRET_ID_T mySecretID;
        SSCS_KEYCHAIN_ID_T mykeychainID;
        SSCS_KEYCHAIN_ID_T newkeychainID;

        memset(&mykeychainID,0,sizeof(SSCS_KEYCHAIN_ID_T));
        testkcId = (wchar_t*)malloc(1024*sizeof(wchar_t));
        assert(testkcId);

//All this required when we have some real wchars :-)
        wcscpy(testkcId,L"SSCS_SESSION_KEY_CHAIN_ID");
        wptr = &testkcId;
        mykeychainID.len = wcsrtombs(testkcIdUTF,wptr,1024,NULL);
        mykeychainID.len+=1;
        memcpy(mykeychainID.keychainID,testkcIdUTF,mykeychainID.len);       

        memset(&mySecretID,0,sizeof(mySecretID));
        testsecretId = (wchar_t*)malloc(1024*sizeof(wchar_t));
        assert(testsecretId);
        wcscpy(testsecretId,L"MySecret");

        wptr = &testsecretId;
        mySecretID.len = wcsrtombs(testsecretIdUTF,wptr,1024,NULL);
        mySecretID.len +=1;
        memcpy(mySecretID.id,testsecretIdUTF,mySecretID.len);

	mySecret.len = MAX_SECRET_VAL_LEN;
	mySecret.data = (char *)malloc(MAX_SECRET_VAL_LEN);
        assert(mySecret.data);

	secID.version = 0x00040000;
        testssName = (wchar_t*)malloc(1024*sizeof(wchar_t));
        assert(testssName);
        wcscpy(testssName,L"SecretStoreName");
        wptr = &testssName;
        n = wcsrtombs(testssNameUTF,wptr,1024,NULL);
        memcpy(secID.ssName,testssNameUTF,n);

	
        ssHandle = sscs_CacheOpenSecretStore(&secID,ssFlags, NULL);
        if(!ssHandle)
        {
                printf("sscs_CacheOpenSecretStore failed\n");
        }
        else
                printf("sscs_CacheOpenSecretStore succesful\n");
    
        ssFlags |= SSCS_SESSION_KEY_CHAIN_F;

        retVal = sscs_CacheAddKeychain(ssHandle,ssFlags,&mykeychainID,NULL);
        if(retVal != 0)
        {
                printf("sscs_CacheAddKeychain failed: %d\n",retVal);
        }
        else
                printf("sscs_CacheAddKeychain succesfully added - %s\n",mykeychainID.keychainID);

        enumerateIDs(ssHandle,0,NULL);
	//Add Secret
	mySecret.len = 4;
	memcpy(mySecret.data,"Test",4);

	retVal = sscs_CacheWriteSecret(ssHandle, ssFlags, &mykeychainID,
                 &mySecretID, &mySecret,&epPassword ,NULL); 
	if(retVal != 0)
	{
		printf("sscs_CacheWriteSecret failed: %d\n",retVal);
	}
	else
		printf("sscs_CacheWriteSecret added to ID - %s\n", mySecretID.id);

        mySecret.len = MAX_SECRET_VAL_LEN;
        memset(mySecret.data,0,MAX_SECRET_VAL_LEN);

        retVal = sscs_CacheReadSecret(ssHandle, ssFlags, &mykeychainID,&mySecretID, &mySecret, &epPassword, &bytesRequired, NULL);
        if(retVal != 0)
        {
                printf("sscs_CacheReadSecret failed: %d\n",retVal);
        }
        else
        {
                printf("sscs_CacheReadSecret- read ID - %s\n",mySecretID.id);
                printf("SecretVal is %s\n",mySecret.data);
        }
//        free(mySecret.data);


        enumerateIDs(ssHandle, 1,&mykeychainID);
        printf("Removing Secret...\n");
        retVal = sscs_CacheRemoveSecret(ssHandle,ssFlags, &mykeychainID,
                 &mySecretID,
                 &epPassword, NULL);
        if(retVal != 0)
        {
                printf("sscs_CacheRemoveSecret failed: %d\n",retVal);
        }
        else
                printf("sscs_CacheRemoveSecret removed id - %S\n",mySecretID.id)
;

        enumerateIDs(ssHandle, 1,&mykeychainID);

        //remove keychain

        printf("Removing Keychain...\n");
        retVal = sscs_CacheRemoveKeychain(ssHandle,ssFlags, &mykeychainID, NULL)
;
        if(retVal != 0)
        {
                printf("sscs_CacheRemoveKeychain failed: %d\n",retVal);
        }
        else
                printf("sscs_CacheRemoveKeychain removed keychain - %s\n",mykeychainID.keychainID);

	enumerateIDs(ssHandle,0,NULL);

        retVal = sscs_CacheCloseSecretStore(ssHandle,ssFlags, NULL);
        if(retVal != 0)
        {
                printf("sscs_CacheCloseSecretStore failed: %d\n",retVal);
        }
        else
                printf("sscs_CacheCloseSecretStore success: %d\n",retVal);

        free(testkcId);
        free(testsecretId);
        free(mySecret.data);
        free(testssName);

	printf("Completed testing\n");
	return 0;
}