/*
 * Setupapi string table functions
 *
 * Copyright 2005 Eric Kohl
 * Copyright 2014 Nikolay Sivov for CodeWeavers
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "winnls.h"
#include "setupapi.h"

#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

DECLARE_HANDLE(HSTRING_TABLE);

struct stringtable {
    char     *data;
    ULONG     nextoffset;
    ULONG     allocated;
    DWORD_PTR unk[2];
    ULONG     max_extra_size;
    LCID      lcid;
};

struct stringentry {
    DWORD nextoffset;
    WCHAR data[1];
};

#define BUCKET_COUNT 509
#define DEFAULT_ALLOC_SIZE 4096

/*
     String table details

 Returned string table 'handle' is a pointer to 'struct stringtable' structure.
 Data itself is allocated separately, pointer is stored in 'data' field.

 Data starts with array of 509 DWORDs - lookup table. Initially all offsets in that
 array are set to -1. Right after lookup table goes data itself, stored in linked lists.
 Lookup table offset points to first record of 'struct stringentry' type. When more
 than one record is present in a bucket, first record links to next one with 'nextoffset'
 field. Last record has nextoffset == -1, same when there's only one record. String data
 is placed right after offset, and is followed by extra data. Each record has reserved
 'max_extra_size' bytes to store extra data, it's not compacted in any way.

 A simple hash function is used to determine which bucket a given string belongs to (see below).

 All offsets including returned string ids are relative to 'data' pointer. When table
 needs to grow 'allocated' size is doubled, but offsets are always valid and preserved.

*/

static inline DWORD get_string_hash(const WCHAR *str, BOOL case_sensitive)
{
    DWORD hash = 0;

    while (*str) {
        WCHAR ch = case_sensitive ? *str : tolowerW(*str);
        hash += ch;
        if (ch & ~0xff)
            hash |= 1;
        str++;
    }

    return hash % BUCKET_COUNT;
}

static inline DWORD *get_bucket_ptr(struct stringtable *table, const WCHAR *string, BOOL case_sensitive)
{
    DWORD hash = get_string_hash(string, case_sensitive);
    return (DWORD*)(table->data + hash*sizeof(DWORD));
}

static inline WCHAR *get_string_ptr(struct stringtable *table, DWORD id)
{
    return (WCHAR*)(table->data + id + sizeof(DWORD));
}

static inline char *get_extradata_ptr(struct stringtable *table, DWORD id)
{
    WCHAR *ptrW = get_string_ptr(table, id);
    /* skip string itself */
    return (char*)(ptrW + strlenW(ptrW) + 1);
}

static inline BOOL is_valid_string_id(struct stringtable *table, DWORD id)
{
    return (id >= BUCKET_COUNT*sizeof(DWORD)) && (id < table->allocated);
}

static inline int get_aligned16_size(int size)
{
    return (size + 15) & ~15;
}

/**************************************************************************
 * StringTableInitializeEx [SETUPAPI.@]
 *
 * Creates a new string table and initializes it.
 *
 * PARAMS
 *     max_extra_size   [I] Maximum extra data size
 *     reserved         [I] Unused
 *
 * RETURNS
 *     Success: Handle to the string table
 *     Failure: NULL
 */
HSTRING_TABLE WINAPI StringTableInitializeEx(ULONG max_extra_size, DWORD reserved)
{
    struct stringtable *table;

    TRACE("(%d %x)\n", max_extra_size, reserved);

    table = MyMalloc(sizeof(*table));
    if (!table) return NULL;

    table->allocated = get_aligned16_size(BUCKET_COUNT*sizeof(DWORD) + DEFAULT_ALLOC_SIZE);
    table->data = MyMalloc(table->allocated);
    if (!table->data) {
        MyFree(table);
        return NULL;
    }

    table->nextoffset = BUCKET_COUNT*sizeof(DWORD);
    /* FIXME: actually these two are not zero */
    table->unk[0] = table->unk[1] = 0;
    table->max_extra_size = max_extra_size;
    table->lcid = GetThreadLocale();

    /* bucket area is filled with 0xff, actual string data area is zeroed */
    memset(table->data, 0xff, table->nextoffset);
    memset(table->data + table->nextoffset, 0, table->allocated - table->nextoffset);

    return (HSTRING_TABLE)table;
}

/**************************************************************************
 * StringTableInitialize [SETUPAPI.@]
 *
 * Creates a new string table and initializes it.
 *
 * PARAMS
 *     None
 *
 * RETURNS
 *     Success: Handle to the string table
 *     Failure: NULL
 */
HSTRING_TABLE WINAPI StringTableInitialize(void)
{
    return StringTableInitializeEx(0, 0);
}

/**************************************************************************
 * StringTableDestroy [SETUPAPI.@]
 *
 * Destroys a string table.
 *
 * PARAMS
 *     hTable [I] Handle to the string table to be destroyed
 *
 * RETURNS
 *     None
 */
void WINAPI StringTableDestroy(HSTRING_TABLE hTable)
{
    struct stringtable *table = (struct stringtable*)hTable;

    TRACE("%p\n", table);

    if (!table)
        return;

    MyFree(table->data);
    MyFree(table);
}

/**************************************************************************
 * StringTableDuplicate [SETUPAPI.@]
 *
 * Duplicates a given string table.
 *
 * PARAMS
 *     hTable [I] Handle to the string table
 *
 * RETURNS
 *     Success: Handle to the duplicated string table
 *     Failure: NULL
 *
 */
HSTRING_TABLE WINAPI StringTableDuplicate(HSTRING_TABLE hTable)
{
    struct stringtable *src = (struct stringtable*)hTable, *dest;

    TRACE("%p\n", src);

    if (!src)
        return NULL;

    dest = MyMalloc(sizeof(*dest));
    if (!dest)
        return NULL;

    *dest = *src;
    dest->data = MyMalloc(src->allocated);
    if (!dest->data) {
        MyFree(dest);
        return NULL;
    }

    memcpy(dest->data, src->data, src->allocated);
    return (HSTRING_TABLE)dest;
}

/**************************************************************************
 * StringTableGetExtraData [SETUPAPI.@]
 *
 * Retrieves extra data from a given string table entry.
 *
 * PARAMS
 *     hTable     [I] Handle to the string table
 *     id         [I] String ID
 *     extra      [I] Pointer a buffer that receives the extra data
 *     extra_size [I] Size of the buffer
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI StringTableGetExtraData(HSTRING_TABLE hTable, ULONG id, void *extra, ULONG extra_size)
{
    struct stringtable *table = (struct stringtable*)hTable;
    char *extraptr;

    TRACE("%p %u %p %u\n", table, id, extra, extra_size);

    if (!table)
        return FALSE;

    if (!is_valid_string_id(table, id))
        return FALSE;

    if (table->max_extra_size > extra_size)
    {
        ERR("data size is too large\n");
        return FALSE;
    }

    extraptr = get_extradata_ptr(table, id);
    memcpy(extra, extraptr, extra_size);
    return TRUE;
}

/**************************************************************************
 * StringTableLookUpStringEx [SETUPAPI.@]
 *
 * Searches a string table and extra data for a given string.
 *
 * PARAMS
 *     hTable      [I] Handle to the string table
 *     string      [I] String to be searched for
 *     flags       [I] Flags
 *                        1: case sensitive compare
 *     extra       [O] Pointer to the buffer that receives the extra data
 *     extra_size  [I/O] Unused
 *
 * RETURNS
 *     Success: String ID
 *     Failure: -1
 */
DWORD WINAPI StringTableLookUpStringEx(HSTRING_TABLE hTable, LPWSTR string, DWORD flags,
    void *extra, ULONG extra_size)
{
    struct stringtable *table = (struct stringtable*)hTable;
    BOOL case_sensitive = flags & 1;
    struct stringentry *entry;
    DWORD offset;
    int cmp;

    TRACE("%p->%p %s %x %p, %x\n", table, table->data, debugstr_w(string), flags, extra, extra_size);

    if (!table)
        return -1;

    /* get corresponding offset */
    offset = *get_bucket_ptr(table, string, case_sensitive);
    if (offset == -1)
        return -1;

    /* now we're at correct bucket, do linear search for string */
    while (1) {
        entry = (struct stringentry*)(table->data + offset);
        if (case_sensitive)
            cmp = lstrcmpW(entry->data, string);
        else
            cmp = lstrcmpiW(entry->data, string);
        if (!cmp) {
            if (extra)
                memcpy(extra, get_extradata_ptr(table, offset), extra_size);
            return offset;
        }

        /* last entry */
        if (entry->nextoffset == -1)
            return -1;

        offset = entry->nextoffset;
        if (offset > table->allocated)
            return -1;
    }
}

/**************************************************************************
 * StringTableLookUpString [SETUPAPI.@]
 *
 * Searches a string table for a given string.
 *
 * PARAMS
 *     hTable  [I] Handle to the string table
 *     string  [I] String to be searched for
 *     flags   [I] Flags
 *                 1: case sensitive compare
 *
 * RETURNS
 *     Success: String ID
 *     Failure: -1
 */
DWORD WINAPI StringTableLookUpString(HSTRING_TABLE hTable, LPWSTR string, DWORD flags)
{
    return StringTableLookUpStringEx(hTable, string, flags, NULL, 0);
}

/**************************************************************************
 * StringTableAddStringEx [SETUPAPI.@]
 *
 * Adds a new string plus extra data to the string table.
 *
 * PARAMS
 *     hTable        [I] Handle to the string table
 *     string        [I] String to be added to the string table
 *     flags         [I] Flags
 *                           1: case sensitive compare
 *     extra         [I] Pointer to the extra data
 *     extra_size    [I] Size of the extra data
 *
 * RETURNS
 *     Success: String ID
 *     Failure: -1
 *
 * NOTES
 *     If the given string already exists in the string table it will not
 *     be added again. The ID of the existing string will be returned in
 *     this case.
 */
DWORD WINAPI StringTableAddStringEx(HSTRING_TABLE hTable, LPWSTR string,
                       DWORD flags, void *extra, DWORD extra_size)
{
    struct stringtable *table = (struct stringtable*)hTable;
    BOOL case_sensitive = flags & 1;
    struct stringentry *entry;
    DWORD id, *offset;
    WCHAR *ptrW;
    int len;

    TRACE("%p %s %x %p, %u\n", hTable, debugstr_w(string), flags, extra, extra_size);

    if (!table)
        return -1;

    id = StringTableLookUpStringEx(hTable, string, flags, NULL, 0);
    if (id != -1)
        return id;

    /* needed space for new record */
    len = sizeof(DWORD) + (strlenW(string)+1)*sizeof(WCHAR) + table->max_extra_size;
    if (table->nextoffset + len >= table->allocated) {
        table->allocated <<= 1;
        table->data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->data, table->allocated);
    }

    /* hash string */
    offset = get_bucket_ptr(table, string, case_sensitive);
    if (*offset == -1)
        /* bucket used for a very first time */
        *offset = table->nextoffset;
    else {
        entry = (struct stringentry*)(table->data + *offset);
        /* link existing last entry to newly added */
        while (entry->nextoffset != -1)
            entry = (struct stringentry*)(table->data + entry->nextoffset);
        entry->nextoffset = table->nextoffset;
    }
    entry = (struct stringentry*)(table->data + table->nextoffset);
    entry->nextoffset = -1;
    id = table->nextoffset;

    /* copy string */
    ptrW = get_string_ptr(table, id);
    strcpyW(ptrW, string);
    if (!case_sensitive)
        strlwrW(ptrW);

    /* copy extra data */
    if (extra)
        memcpy(get_extradata_ptr(table, id), extra, extra_size);

    table->nextoffset += len;
    return id;
}

/**************************************************************************
 * StringTableAddString [SETUPAPI.@]
 *
 * Adds a new string to the string table.
 *
 * PARAMS
 *     hTable     [I] Handle to the string table
 *     string     [I] String to be added to the string table
 *     flags      [I] Flags
 *                        1: case sensitive compare
 *
 * RETURNS
 *     Success: String ID
 *     Failure: -1
 *
 * NOTES
 *     If the given string already exists in the string table it will not
 *     be added again. The ID of the existing string will be returned in
 *     this case.
 */
DWORD WINAPI StringTableAddString(HSTRING_TABLE hTable, LPWSTR string, DWORD flags)
{
    return StringTableAddStringEx(hTable, string, flags, NULL, 0);
}

/**************************************************************************
 * StringTableSetExtraData [SETUPAPI.@]
 *
 * Sets extra data for a given string table entry.
 *
 * PARAMS
 *     hTable     [I] Handle to the string table
 *     id         [I] String ID
 *     extra      [I] Pointer to the extra data
 *     extra_size [I] Size of the extra data
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI StringTableSetExtraData(HSTRING_TABLE hTable, DWORD id, void *extra, ULONG extra_size)
{
    struct stringtable *table = (struct stringtable*)hTable;
    char *extraptr;

    TRACE("%p %d %p %u\n", hTable, id, extra, extra_size);

    if (!table)
        return FALSE;

    if (!is_valid_string_id(table, id))
        return FALSE;

    if (table->max_extra_size < extra_size)
    {
        ERR("data size is too large\n");
        return FALSE;
    }

    extraptr = get_extradata_ptr(table, id);
    memset(extraptr, 0, table->max_extra_size);
    memcpy(extraptr, extra, extra_size);

    return TRUE;
}

/**************************************************************************
 * StringTableStringFromId [SETUPAPI.@]
 *
 * Returns a pointer to a string for the given string ID.
 *
 * PARAMS
 *     hTable [I] Handle to the string table.
 *     id     [I] String ID
 *
 * RETURNS
 *     Success: Pointer to the string
 *     Failure: NULL
 */
LPWSTR WINAPI StringTableStringFromId(HSTRING_TABLE hTable, ULONG id)
{
    struct stringtable *table = (struct stringtable*)hTable;
    static WCHAR empty[] = {0};

    TRACE("%p %d\n", table, id);

    if (!table)
        return NULL;

    if (!is_valid_string_id(table, id))
        return empty;

    return get_string_ptr(table, id);
}

/**************************************************************************
 * StringTableStringFromIdEx [SETUPAPI.@]
 *
 * Returns a string for the given string ID.
 *
 * PARAMS
 *     hTable   [I] Handle to the string table
 *     id       [I] String ID
 *     buff     [I] Pointer to string buffer
 *     buflen   [I/O] Pointer to the size of the string buffer
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI StringTableStringFromIdEx(HSTRING_TABLE hTable, ULONG id, LPWSTR buff, DWORD *buflen)
{
    struct stringtable *table = (struct stringtable*)hTable;
    BOOL ret = TRUE;
    WCHAR *ptrW;
    int len;

    TRACE("%p %x %p %p\n", table, id, buff, buflen);

    if (!table) {
        *buflen = 0;
        return FALSE;
    }

    if (!is_valid_string_id(table, id)) {
        WARN("invalid string id\n");
        *buflen = 0;
        return FALSE;
    }

    ptrW = get_string_ptr(table, id);
    len = (strlenW(ptrW) + 1)*sizeof(WCHAR);
    if (len <= *buflen)
        strcpyW(buff, ptrW);
    else
        ret = FALSE;

    *buflen = len;
    return ret;
}

/**************************************************************************
 * StringTableTrim [SETUPAPI.@]
 *
 * ...
 *
 * PARAMS
 *     hTable [I] Handle to the string table
 *
 * RETURNS
 *     None
 */
void WINAPI StringTableTrim(HSTRING_TABLE hTable)
{
    FIXME("%p\n", hTable);
}
