/***********************************************************************
 * 
 *  Copyright (C) 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.
 * 
 *  Author: Juan Carlos Luciani <jluciani@novell.com>
 *
 ***********************************************************************/

//===[ Include files ]=====================================================

#include "internal.h"

//===[ Type definitions ]==================================================

//
// Authentication Token Interface instance data
// 
typedef struct _AuthTokenIfInstance
{
   int            refCount;
   AuthTokenIf    authTokenIf;

} AuthTokenIfInstance, *PAuthTokenIfInstance;

//===[ Function prototypes ]===============================================

//===[ Global variables ]==================================================

// AuthTokenIf variables
static
int   g_numAuthTokenIfObjs = 0;


//++=======================================================================
static
int SSCS_CALL
AuthTokenIf_AddReference(
   IN       const void  *pIfInstance)
//
// Arguments:  
//    pIfInstance -
//       Pointer to interface object.
//   
// Returns:
//    Interface reference count.
//                           
// Description:
//    Increases interface reference count.
//
// L2
//=======================================================================--
{
   int                  refCount;
   AuthTokenIfInstance  *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf);

   DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0);

   // Increment the reference count on the object
   pAuthTokenIfInstance->refCount ++;
   refCount = pAuthTokenIfInstance->refCount;

   DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %0X\n", refCount);

   return refCount;
}


//++=======================================================================
static
void SSCS_CALL
AuthTokenIf_ReleaseReference(
   IN       const void  *pIfInstance)
//
// Arguments:  
//    pIfInstance -
//       Pointer to interface object.
//   
// Returns:
//    Nothing.
//                           
// Description:
//    Decreases interface reference count. The interface is deallocated if
//    the reference count becomes zero.
//
// L2
//=======================================================================--
{
   bool                 freeObj = false;
   AuthTokenIfInstance  *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf);

   DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0);

   // Decrement the reference count on the object and determine if it needs to
   // be released.
   pAuthTokenIfInstance->refCount --;
   if (pAuthTokenIfInstance->refCount == 0)
   {
      // The object needs to be released, forget about it.
      freeObj = true;
      g_numAuthTokenIfObjs --;
   }

   // Free object if necessary
   if (freeObj)
      free(pAuthTokenIfInstance);

   DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0);
}


//++=======================================================================
CasaStatus SSCS_CALL
GET_AUTH_TOKEN_INTERFACE_RTN(
   IN       const ConfigIf    *pModuleConfigIf,
   INOUT    AuthTokenIf       **ppAuthTokenIf)
//
// Arguments:  
//    pModuleConfigIf -
//       Pointer to configuration interface instance for the module.
//               
//    ppAuthTokenIf -
//       Pointer to variable that will receive pointer to AuthTokenIf
//       instance.
//
// Returns:
//    Casa Status
//                           
// Description:
//    Gets authentication token interface instance.
//
// L2
//=======================================================================--
{
   CasaStatus           retStatus;
   AuthTokenIfInstance  *pAuthTokenIfInstance;
   char                 *pDebugLevelSetting;

   DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0);

   // Validate input parameters
   if (pModuleConfigIf == NULL
       || ppAuthTokenIf == NULL)
   {
      DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0);

      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
                                  CASA_FACILITY_PWTOKEN,
                                  CASA_STATUS_INVALID_PARAMETER);
      goto exit;
   }

   // Check if a DebugLevel has been configured
   pDebugLevelSetting = pModuleConfigIf->getEntryValue(pModuleConfigIf, "DebugLevel");
   if (pDebugLevelSetting != NULL)
   {
      DbgTrace(0, "-GetAuthTokenInterface- DebugLevel configured = %s\n", pDebugLevelSetting);
      
      // Convert the number to hex
      DebugLevel = (int) dtoul(pDebugLevelSetting, strlen(pDebugLevelSetting));

      // Free the buffer holding the debug level
      free(pDebugLevelSetting);
   }

   // Allocate space for the interface instance
   pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance));
   if (pAuthTokenIfInstance)
   {
      // Initialize the interface instance data
      pAuthTokenIfInstance->refCount = 1;
      pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference;
      pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference;
      pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken;

      // Keep track of this object
      g_numAuthTokenIfObjs ++;

      // Return the interface to the caller
      *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf;

      // Success
      retStatus = CASA_STATUS_SUCCESS;
   }
   else
   {
      DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0);

      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
                                  CASA_FACILITY_PWTOKEN,
                                  CASA_STATUS_INSUFFICIENT_RESOURCES);
   }

exit:

   DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %0X\n", retStatus);

   return retStatus;
}


//++=======================================================================
//++=======================================================================
//++=======================================================================