/* Copyright (c) 2003 Juan Lang
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * This implementation uses a linked list, because I don't have a decent
 * hash table implementation handy.  This is somewhat inefficient, but it's
 * rather more efficient than not having a name cache at all.
 */

#include "config.h"
#include "wine/port.h"
#include "wine/debug.h"

#include "nbnamecache.h"

WINE_DEFAULT_DEBUG_CHANNEL(netbios);

typedef struct _NBNameCacheNode
{
    DWORD expireTime;
    NBNameCacheEntry *entry;
    struct _NBNameCacheNode *next;
} NBNameCacheNode;

struct NBNameCache
{
    HANDLE heap;
    CRITICAL_SECTION cs;
    DWORD entryExpireTimeMS;
    NBNameCacheNode *head;
};

/* Unlinks the node pointed to by *prev, and frees any associated memory.
 * If that node's next pointed to another node, *prev now points to it.
 * Assumes the caller owns cache's lock.
 */
static void NBNameCacheUnlinkNode(struct NBNameCache *cache,
 NBNameCacheNode **prev)
{
    if (cache && prev && *prev)
    {
        NBNameCacheNode *next = (*prev)->next;

        HeapFree(cache->heap, 0, (*prev)->entry);
        HeapFree(cache->heap, 0, *prev);
        *prev = next;
    }
}

/* Walks the list beginning with cache->head looking for the node with name
 * name.  If the node is found, returns a pointer to the next pointer of the
 * node _prior_ to the found node (or head if head points to it).  Thus, if the
 * node's all you want, dereference the return value twice.  If you want to
 * modify the list, modify the referent of the return value.
 * While it's at it, deletes nodes whose time has expired (except the node
 * you're looking for, of course).
 * Returns NULL if the node isn't found.
 * Assumes the caller owns cache's lock.
 */
static NBNameCacheNode **NBNameCacheWalk(struct NBNameCache *cache,
 const char name[NCBNAMSZ])
{
    NBNameCacheNode **ret = NULL;

    if (cache && cache->head)
    {
        NBNameCacheNode **ptr;

        ptr = &cache->head;
        while (ptr && *ptr && (*ptr)->entry)
        {
            if (!memcmp((*ptr)->entry->name, name, NCBNAMSZ - 1))
                ret = ptr;
            else
            {
                if (GetTickCount() > (*ptr)->expireTime)
                    NBNameCacheUnlinkNode(cache, ptr);
            }
            if (*ptr)
                ptr = &(*ptr)->next;
        }
    }
    return ret;
}

struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS)
{
    struct NBNameCache *cache;
    
    
    if (!heap)
        heap = GetProcessHeap();
    cache = (struct NBNameCache *)HeapAlloc(heap, 0,
     sizeof(struct NBNameCache));
    if (cache)
    {
        cache->heap = heap;
        InitializeCriticalSection(&cache->cs);
        cache->entryExpireTimeMS = entryExpireTimeMS;
        cache->head = NULL;
    }
    return cache;
}

BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry)
{
    BOOL ret;

    if (cache && entry)
    {
        NBNameCacheNode **node;

        EnterCriticalSection(&cache->cs);
        node = NBNameCacheWalk(cache, entry->name);
        if (node)
        {
            (*node)->expireTime = GetTickCount() +
             cache->entryExpireTimeMS;
            HeapFree(cache->heap, 0, (*node)->entry);
            (*node)->entry = entry;
            ret = TRUE;
        }
        else
        {
            NBNameCacheNode *newNode = (NBNameCacheNode *)HeapAlloc(
             cache->heap, 0, sizeof(NBNameCacheNode));
            if (newNode)
            {
                newNode->expireTime = GetTickCount() +
                 cache->entryExpireTimeMS;
                newNode->entry = entry;
                newNode->next = cache->head;
                cache->head = newNode;
                ret = TRUE;
            }
            else
                ret = FALSE;
        }
        LeaveCriticalSection(&cache->cs);
    }
    else
        ret = FALSE;
    return ret;
}

const NBNameCacheEntry *NBNameCacheFindEntry(struct NBNameCache *cache,
 const UCHAR name[NCBNAMSZ])
{
    const NBNameCacheEntry *ret;
    UCHAR printName[NCBNAMSZ];

    memcpy(printName, name, NCBNAMSZ - 1);
    printName[NCBNAMSZ - 1] = '\0';
    if (cache)
    {
        NBNameCacheNode **node;

        EnterCriticalSection(&cache->cs);
        node = NBNameCacheWalk(cache, name);
        if (node)
            ret = (*node)->entry;
        else
            ret = NULL;
        LeaveCriticalSection(&cache->cs);
    }
    else
        ret = NULL;
    return ret;
}

BOOL NBNameCacheUpdateNBName(struct NBNameCache *cache,
 const UCHAR name[NCBNAMSZ], const UCHAR nbname[NCBNAMSZ])
{
    BOOL ret;

    if (cache)
    {
        NBNameCacheNode **node;

        EnterCriticalSection(&cache->cs);
        node = NBNameCacheWalk(cache, name);
        if (node && *node && (*node)->entry)
        {
            memcpy((*node)->entry->nbname, nbname, NCBNAMSZ);
            ret = TRUE;
        }
        else
            ret = FALSE;
        LeaveCriticalSection(&cache->cs);
    }
    else
        ret = FALSE;
    return ret;
}

void NBNameCacheDestroy(struct NBNameCache *cache)
{
    if (cache)
    {
        DeleteCriticalSection(&cache->cs);
        while (cache->head)
            NBNameCacheUnlinkNode(cache, &cache->head);
        HeapFree(cache->heap, 0, cache);
    }
}
