/*
 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
 * 
 * The contents of this file constitute Original Code as defined in and are
 * subject to the Apple Public Source License Version 1.2 (the 'License').
 * You may not use this file except in compliance with the License. Please obtain
 * a copy of the License at http://www.apple.com/publicsource and read it before
 * using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
 * specific language governing rights and limitations under the License.
 */


/*

   File:      mds.h

   Contains:  Module Directory Services Data Types and API.

   Copyright: (c) 1999 Apple Computer, Inc., all rights reserved.

   This is the C API wrapper for the C++ MDS implementation.  Most of this file
   could also be generated by the same perl script that generates the plugin
   C wrapper code.

 */

#include "MDSSession.h"

#include <memory>

using namespace std;

static CSSM_RETURN CSSMAPI cssm_DataGetFirst(CSSM_DL_DB_HANDLE DLDBHandle,
         const CSSM_QUERY *Query,
         CSSM_HANDLE_PTR ResultsHandle,
         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
         CSSM_DATA_PTR Data,
         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
{
  BEGIN_API
  if (!(Required(ResultsHandle) = findHandle<MDSSession>(DLDBHandle.DLHandle).DataGetFirst(DLDBHandle.DBHandle,
			DLQuery::optional(Query),
			Attributes,
			CssmData::optional(Data),
			Required(UniqueId))))
	return CSSMERR_DL_ENDOFDATA;
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DataModify(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_DB_RECORDTYPE RecordType,
         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier,
         const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
         const CSSM_DATA *DataToBeModified,
         CSSM_DB_MODIFY_MODE ModifyMode)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DataModify(DLDBHandle.DBHandle,
			RecordType,
			Required(UniqueRecordIdentifier),
			AttributesToBeModified,
			CssmData::optional(DataToBeModified),
			ModifyMode);
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_GetDbNameFromHandle(CSSM_DL_DB_HANDLE DLDBHandle,
         char **DbName)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).GetDbNameFromHandle(DLDBHandle.DBHandle,
			DbName);
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DataAbortQuery(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_HANDLE ResultsHandle)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DataAbortQuery(DLDBHandle.DBHandle,
			ResultsHandle);
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DestroyRelation(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_DB_RECORDTYPE RelationID)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DestroyRelation(DLDBHandle.DBHandle,
			RelationID);
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DataDelete(CSSM_DL_DB_HANDLE DLDBHandle,
         const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DataDelete(DLDBHandle.DBHandle,
			Required(UniqueRecordIdentifier));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DataInsert(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_DB_RECORDTYPE RecordType,
         const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
         const CSSM_DATA *Data,
         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DataInsert(DLDBHandle.DBHandle,
			RecordType,
			Attributes,
			CssmData::optional(Data),
			Required(UniqueId));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DataGetFromUniqueRecordId(CSSM_DL_DB_HANDLE DLDBHandle,
         const CSSM_DB_UNIQUE_RECORD *UniqueRecord,
         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
         CSSM_DATA_PTR Data)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DataGetFromUniqueRecordId(DLDBHandle.DBHandle,
			Required(UniqueRecord),
            Attributes,
			CssmData::optional(Data));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_CreateRelation(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_DB_RECORDTYPE RelationID,
         const char *RelationName,
         uint32 NumberOfAttributes,
         const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
         uint32 NumberOfIndexes,
         const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).CreateRelation(DLDBHandle.DBHandle,
			RelationID,
			RelationName,
			NumberOfAttributes,
			Required(pAttributeInfo),
			NumberOfIndexes,
			Required(pIndexInfo));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_FreeUniqueRecord(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).FreeUniqueRecord(DLDBHandle.DBHandle,
			Required(UniqueRecord));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DbOpen(CSSM_DL_HANDLE DLHandle,
         const char *DbName,
         const CSSM_NET_ADDRESS *DbLocation,
         CSSM_DB_ACCESS_TYPE AccessRequest,
         const CSSM_ACCESS_CREDENTIALS *AccessCred,
         const void *OpenParameters,
         CSSM_DB_HANDLE *DbHandle)
{
  BEGIN_API
  findHandle<MDSSession>(DLHandle).DbOpen(DbName,
			DbLocation,
			AccessRequest,
			AccessCredentials::optional(AccessCred),
			OpenParameters,
			Required(DbHandle));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DataGetNext(CSSM_DL_DB_HANDLE DLDBHandle,
         CSSM_HANDLE ResultsHandle,
         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
         CSSM_DATA_PTR Data,
         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
{
  BEGIN_API
  if (!findHandle<MDSSession>(DLDBHandle.DLHandle).DataGetNext(DLDBHandle.DBHandle,
			ResultsHandle,
			Attributes,
			CssmData::optional(Data),
			Required(UniqueId)))
	return CSSMERR_DL_ENDOFDATA;
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_GetDbNames(CSSM_DL_HANDLE DLHandle,
         CSSM_NAME_LIST_PTR *NameList)
{
  BEGIN_API
  findHandle<MDSSession>(DLHandle).GetDbNames(Required(NameList));
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_DbClose(CSSM_DL_DB_HANDLE DLDBHandle)
{
  BEGIN_API
  findHandle<MDSSession>(DLDBHandle.DLHandle).DbClose(DLDBHandle.DBHandle);
  END_API(MDS)
}

static CSSM_RETURN CSSMAPI cssm_FreeNameList(CSSM_DL_HANDLE DLHandle,
         CSSM_NAME_LIST_PTR NameList)
{
  BEGIN_API
  findHandle<MDSSession>(DLHandle).FreeNameList(Required(NameList));
  END_API(MDS)
}

static MDS_FUNCS gMDSFunctionTable =
{
    cssm_DbOpen,
    cssm_DbClose,
    cssm_GetDbNames,
    cssm_GetDbNameFromHandle,
    cssm_FreeNameList,
    cssm_DataInsert,
    cssm_DataDelete,
    cssm_DataModify,
    cssm_DataGetFirst,
    cssm_DataGetNext,
    cssm_DataAbortQuery,
    cssm_DataGetFromUniqueRecordId,
    cssm_FreeUniqueRecord,
    cssm_CreateRelation,
    cssm_DestroyRelation,
};


#ifdef __MWERKS__
#pragma export on
#endif

CSSM_RETURN CSSMAPI
MDS_Initialize (const CSSM_GUID *inCallerGuid,
                const CSSM_MEMORY_FUNCS *inMemoryFunctions,
                MDS_FUNCS_PTR outDlFunctions,
                MDS_HANDLE *outMDSHandle)
{
    BEGIN_API
    Required (outDlFunctions);
    Required (outMDSHandle) = (new MDSSession (Guid::optional(inCallerGuid),
                                               Required(inMemoryFunctions)))->handle ();
    *outDlFunctions = gMDSFunctionTable;
    END_API(MDS)
}

CSSM_RETURN CSSMAPI
MDS_Terminate (MDS_HANDLE inMDSHandle)
{
    BEGIN_API
    auto_ptr<MDSSession> aMDSSession (&killHandle<MDSSession> (inMDSHandle));
    aMDSSession->terminate (); // Even if terminate throws the MDSSession object will be deleted.
    END_API(MDS)
}

CSSM_RETURN CSSMAPI
MDS_Install (MDS_HANDLE inMDSHandle)
{
    BEGIN_API
    findHandle<MDSSession> (inMDSHandle).install ();
    END_API(MDS)
}

CSSM_RETURN CSSMAPI
MDS_Uninstall (MDS_HANDLE inMDSHandle)
{
    BEGIN_API
    findHandle<MDSSession> (inMDSHandle).uninstall ();
    END_API(MDS)
}

#ifdef __MWERKS__
#pragma export off
#endif
