/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * hash.c
 *
 * This is merely a couple wrappers around NSPR's PLHashTable, using
 * the identity hash and arena-aware allocators.  The reason I did
 * this is that hash tables are used in a few places throughout the
 * NSS Cryptoki Framework in a fairly stereotyped way, and this allows
 * me to pull the commonalities into one place.  Should we ever want
 * to change the implementation, it's all right here.
 */

#ifndef CK_T
#include "ck.h"
#endif /* CK_T */

/*
 * nssCKFWHash
 *
 *  nssCKFWHash_Create
 *  nssCKFWHash_Destroy
 *  nssCKFWHash_Add
 *  nssCKFWHash_Remove
 *  nssCKFWHash_Count
 *  nssCKFWHash_Exists
 *  nssCKFWHash_Lookup
 *  nssCKFWHash_Iterate
 */

struct nssCKFWHashStr {
    NSSCKFWMutex *mutex;

    /*
     * The invariant that mutex protects is:
     *   The count accurately reflects the hashtable state.
     */

    PLHashTable *plHashTable;
    CK_ULONG count;
};

static PLHashNumber
nss_ckfw_identity_hash(
    const void *key)
{
    return (PLHashNumber)((char *)key - (char *)NULL);
}

/*
 * nssCKFWHash_Create
 *
 */
NSS_IMPLEMENT nssCKFWHash *
nssCKFWHash_Create(
    NSSCKFWInstance *fwInstance,
    NSSArena *arena,
    CK_RV *pError)
{
    nssCKFWHash *rv;

#ifdef NSSDEBUG
    if (!pError) {
        return (nssCKFWHash *)NULL;
    }

    if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
        *pError = CKR_ARGUMENTS_BAD;
        return (nssCKFWHash *)NULL;
    }
#endif /* NSSDEBUG */

    rv = nss_ZNEW(arena, nssCKFWHash);
    if (!rv) {
        *pError = CKR_HOST_MEMORY;
        return (nssCKFWHash *)NULL;
    }

    rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
    if (!rv->mutex) {
        if (CKR_OK == *pError) {
            *pError = CKR_GENERAL_ERROR;
        }
        (void)nss_ZFreeIf(rv);
        return (nssCKFWHash *)NULL;
    }

    rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash,
                                      PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena);
    if (!rv->plHashTable) {
        (void)nssCKFWMutex_Destroy(rv->mutex);
        (void)nss_ZFreeIf(rv);
        *pError = CKR_HOST_MEMORY;
        return (nssCKFWHash *)NULL;
    }

    rv->count = 0;

    return rv;
}

/*
 * nssCKFWHash_Destroy
 *
 */
NSS_IMPLEMENT void
nssCKFWHash_Destroy(
    nssCKFWHash *hash)
{
    (void)nssCKFWMutex_Destroy(hash->mutex);
    PL_HashTableDestroy(hash->plHashTable);
    (void)nss_ZFreeIf(hash);
}

/*
 * nssCKFWHash_Add
 *
 */
NSS_IMPLEMENT CK_RV
nssCKFWHash_Add(
    nssCKFWHash *hash,
    const void *key,
    const void *value)
{
    CK_RV error = CKR_OK;
    PLHashEntry *he;

    error = nssCKFWMutex_Lock(hash->mutex);
    if (CKR_OK != error) {
        return error;
    }

    he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
    if (!he) {
        error = CKR_HOST_MEMORY;
    } else {
        hash->count++;
    }

    (void)nssCKFWMutex_Unlock(hash->mutex);

    return error;
}

/*
 * nssCKFWHash_Remove
 *
 */
NSS_IMPLEMENT void
nssCKFWHash_Remove(
    nssCKFWHash *hash,
    const void *it)
{
    PRBool found;

    if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
        return;
    }

    found = PL_HashTableRemove(hash->plHashTable, it);
    if (found) {
        hash->count--;
    }

    (void)nssCKFWMutex_Unlock(hash->mutex);
    return;
}

/*
 * nssCKFWHash_Count
 *
 */
NSS_IMPLEMENT CK_ULONG
nssCKFWHash_Count(
    nssCKFWHash *hash)
{
    CK_ULONG count;

    if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
        return (CK_ULONG)0;
    }

    count = hash->count;

    (void)nssCKFWMutex_Unlock(hash->mutex);

    return count;
}

/*
 * nssCKFWHash_Exists
 *
 */
NSS_IMPLEMENT CK_BBOOL
nssCKFWHash_Exists(
    nssCKFWHash *hash,
    const void *it)
{
    void *value;

    if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
        return CK_FALSE;
    }

    value = PL_HashTableLookup(hash->plHashTable, it);

    (void)nssCKFWMutex_Unlock(hash->mutex);

    if (!value) {
        return CK_FALSE;
    } else {
        return CK_TRUE;
    }
}

/*
 * nssCKFWHash_Lookup
 *
 */
NSS_IMPLEMENT void *
nssCKFWHash_Lookup(
    nssCKFWHash *hash,
    const void *it)
{
    void *rv;

    if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
        return (void *)NULL;
    }

    rv = PL_HashTableLookup(hash->plHashTable, it);

    (void)nssCKFWMutex_Unlock(hash->mutex);

    return rv;
}

struct arg_str {
    nssCKFWHashIterator fcn;
    void *closure;
};

static PRIntn
nss_ckfwhash_enumerator(
    PLHashEntry *he,
    PRIntn index,
    void *arg)
{
    struct arg_str *as = (struct arg_str *)arg;
    as->fcn(he->key, he->value, as->closure);
    return HT_ENUMERATE_NEXT;
}

/*
 * nssCKFWHash_Iterate
 *
 * NOTE that the iteration function will be called with the hashtable locked.
 */
NSS_IMPLEMENT void
nssCKFWHash_Iterate(
    nssCKFWHash *hash,
    nssCKFWHashIterator fcn,
    void *closure)
{
    struct arg_str as;
    as.fcn = fcn;
    as.closure = closure;

    if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
        return;
    }

    PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);

    (void)nssCKFWMutex_Unlock(hash->mutex);

    return;
}
