/* 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 = 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, (char*)entry->name);
        if (node)
        {
            (*node)->expireTime = GetTickCount() +
             cache->entryExpireTimeMS;
            HeapFree(cache->heap, 0, (*node)->entry);
            (*node)->entry = entry;
            ret = TRUE;
        }
        else
        {
            NBNameCacheNode *newNode = 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, (char*)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, (char*)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);
    }
}
