/*
 * propsys main
 *
 * Copyright 1997, 2002 Alexandre Julliard
 * Copyright 2008 James Hawkins
 *
 * 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
 */

#define COBJMACROS
#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "rpcproxy.h"
#include "propsys.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#include "propsys_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(propsys);

static HINSTANCE propsys_hInstance;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
        case DLL_WINE_PREATTACH:
            return FALSE;    /* prefer native version */
        case DLL_PROCESS_ATTACH:
            propsys_hInstance = hinstDLL;
            DisableThreadLibraryCalls(hinstDLL);
            break;
    }

    return TRUE;
}

HRESULT WINAPI DllRegisterServer(void)
{
    return __wine_register_resources( propsys_hInstance );
}

HRESULT WINAPI DllUnregisterServer(void)
{
    return __wine_unregister_resources( propsys_hInstance );
}

static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
        TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
        *ppv = iface;
    }

    if(*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
    return E_NOINTERFACE;
}

static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
{
    TRACE("(%p)\n", iface);
    return 2;
}

static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
    TRACE("(%p)\n", iface);
    return 1;
}

static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
{
    TRACE("(%p)->(%x)\n", iface, fLock);

    return S_OK;
}

static HRESULT WINAPI InMemoryPropertyStoreFactory_CreateInstance(IClassFactory *iface, IUnknown *outer,
        REFIID riid, void **ppv)
{
    TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);

    return PropertyStore_CreateInstance(outer, riid, ppv);
}

static const IClassFactoryVtbl InMemoryPropertyStoreFactoryVtbl = {
    ClassFactory_QueryInterface,
    ClassFactory_AddRef,
    ClassFactory_Release,
    InMemoryPropertyStoreFactory_CreateInstance,
    ClassFactory_LockServer
};

static IClassFactory InMemoryPropertyStoreFactory = { &InMemoryPropertyStoreFactoryVtbl };

HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    if(IsEqualGUID(&CLSID_InMemoryPropertyStore, rclsid)) {
        TRACE("(CLSID_InMemoryPropertyStore %s %p)\n", debugstr_guid(riid), ppv);
        return IClassFactory_QueryInterface(&InMemoryPropertyStoreFactory, riid, ppv);
    }

    FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    return CLASS_E_CLASSNOTAVAILABLE;
}

HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_FALSE;
}

static HRESULT WINAPI propsys_QueryInterface(IPropertySystem *iface, REFIID riid, void **obj)
{
    *obj = NULL;

    if (IsEqualIID(riid, &IID_IPropertySystem) || IsEqualIID(riid, &IID_IUnknown)) {
        *obj = iface;
        IPropertySystem_AddRef(iface);
        return S_OK;
    }

    FIXME("%s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI propsys_AddRef(IPropertySystem *iface)
{
    return 2;
}

static ULONG WINAPI propsys_Release(IPropertySystem *iface)
{
    return 1;
}

static HRESULT WINAPI propsys_GetPropertyDescription(IPropertySystem *iface,
    REFPROPERTYKEY propkey, REFIID riid, void **ppv)
{
    return PSGetPropertyDescription(propkey, riid, ppv);
}

static HRESULT WINAPI propsys_GetPropertyDescriptionByName(IPropertySystem *iface,
    LPCWSTR canonical_name, REFIID riid, void **ppv)
{
    FIXME("%s %s %p: stub\n", debugstr_w(canonical_name), debugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI propsys_GetPropertyDescriptionListFromString(IPropertySystem *iface,
    LPCWSTR proplist, REFIID riid, void **ppv)
{
    return PSGetPropertyDescriptionListFromString(proplist, riid, ppv);
}

static HRESULT WINAPI propsys_EnumeratePropertyDescriptions(IPropertySystem *iface,
    PROPDESC_ENUMFILTER filter, REFIID riid, void **ppv)
{
    FIXME("%d %s %p: stub\n", filter, debugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI propsys_FormatForDisplay(IPropertySystem *iface,
    REFPROPERTYKEY key, REFPROPVARIANT propvar, PROPDESC_FORMAT_FLAGS flags,
    LPWSTR dest, DWORD destlen)
{
    FIXME("%p %p %x %p %d: stub\n", key, propvar, flags, dest, destlen);
    return E_NOTIMPL;
}

static HRESULT WINAPI propsys_FormatForDisplayAlloc(IPropertySystem *iface,
    REFPROPERTYKEY key, REFPROPVARIANT propvar, PROPDESC_FORMAT_FLAGS flags,
    LPWSTR *text)
{
    FIXME("%p %p %x %p: stub\n", key, propvar, flags, text);
    return E_NOTIMPL;
}

static HRESULT WINAPI propsys_RegisterPropertySchema(IPropertySystem *iface, LPCWSTR path)
{
    return PSRegisterPropertySchema(path);
}

static HRESULT WINAPI propsys_UnregisterPropertySchema(IPropertySystem *iface, LPCWSTR path)
{
    return PSUnregisterPropertySchema(path);
}

static HRESULT WINAPI propsys_RefreshPropertySchema(IPropertySystem *iface)
{
    return PSRefreshPropertySchema();
}

static const IPropertySystemVtbl propsysvtbl = {
    propsys_QueryInterface,
    propsys_AddRef,
    propsys_Release,
    propsys_GetPropertyDescription,
    propsys_GetPropertyDescriptionByName,
    propsys_GetPropertyDescriptionListFromString,
    propsys_EnumeratePropertyDescriptions,
    propsys_FormatForDisplay,
    propsys_FormatForDisplayAlloc,
    propsys_RegisterPropertySchema,
    propsys_UnregisterPropertySchema,
    propsys_RefreshPropertySchema
};

static IPropertySystem propsys = { &propsysvtbl };

HRESULT WINAPI PSGetPropertySystem(REFIID riid, void **obj)
{
    return IPropertySystem_QueryInterface(&propsys, riid, obj);
}

HRESULT WINAPI PSRegisterPropertySchema(PCWSTR path)
{
    FIXME("%s stub\n", debugstr_w(path));

    return S_OK;
}

HRESULT WINAPI PSUnregisterPropertySchema(PCWSTR path)
{
    FIXME("%s stub\n", debugstr_w(path));

    return E_NOTIMPL;
}

HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY propkey, REFIID riid, void **ppv)
{
    FIXME("%p, %p, %p\n", propkey, riid, ppv);
    return E_NOTIMPL;
}

HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR proplist, REFIID riid, void **ppv)
{
    FIXME("%s, %p, %p\n", debugstr_w(proplist), riid, ppv);
    return E_NOTIMPL;
}

HRESULT WINAPI PSRefreshPropertySchema(void)
{
    FIXME("\n");
    return S_OK;
}

HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch)
{
    static const WCHAR guid_fmtW[] = {'{','%','0','8','X','-','%','0','4','X','-',
                                      '%','0','4','X','-','%','0','2','X','%','0','2','X','-',
                                      '%','0','2','X','%','0','2','X','%','0','2','X',
                                      '%','0','2','X','%','0','2','X','%','0','2','X','}',0};
    static const WCHAR pid_fmtW[] = {'%','u',0};

    WCHAR pidW[PKEY_PIDSTR_MAX + 1];
    LPWSTR p = psz;
    int len;

    TRACE("(%p, %p, %u)\n", pkey, psz, cch);

    if (!psz)
        return E_POINTER;

    /* GUIDSTRING_MAX accounts for null terminator, +1 for space character. */
    if (cch <= GUIDSTRING_MAX + 1)
        return E_NOT_SUFFICIENT_BUFFER;

    if (!pkey)
    {
        psz[0] = '\0';
        return E_NOT_SUFFICIENT_BUFFER;
    }

    sprintfW(psz, guid_fmtW, pkey->fmtid.Data1, pkey->fmtid.Data2,
             pkey->fmtid.Data3, pkey->fmtid.Data4[0], pkey->fmtid.Data4[1],
             pkey->fmtid.Data4[2], pkey->fmtid.Data4[3], pkey->fmtid.Data4[4],
             pkey->fmtid.Data4[5], pkey->fmtid.Data4[6], pkey->fmtid.Data4[7]);

    /* Overwrite the null terminator with the space character. */
    p += GUIDSTRING_MAX - 1;
    *p++ = ' ';
    cch -= GUIDSTRING_MAX - 1 + 1;

    len = sprintfW(pidW, pid_fmtW, pkey->pid);

    if (cch >= len + 1)
    {
        strcpyW(p, pidW);
        return S_OK;
    }
    else
    {
        WCHAR *ptr = pidW + len - 1;

        psz[0] = '\0';
        *p++ = '\0';
        cch--;

        /* Replicate a quirk of the native implementation where the contents
         * of the property ID string are written backwards to the output
         * buffer, skipping the rightmost digit. */
        if (cch)
        {
            ptr--;
            while (cch--)
                *p++ = *ptr--;
        }

        return E_NOT_SUFFICIENT_BUFFER;
    }
}

static const BYTE hex2bin[] =
{
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x00 */
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x10 */
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x20 */
    0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,        /* 0x30 */
    0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,  /* 0x40 */
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x50 */
    0,10,11,12,13,14,15                     /* 0x60 */
};

static BOOL validate_indices(LPCWSTR s, int min, int max)
{
    int i;

    for (i = min; i <= max; i++)
    {
        if (!s[i])
            return FALSE;

        if (i == 0)
        {
            if (s[i] != '{')
                return FALSE;
        }
        else if (i == 9 || i == 14 || i == 19 || i == 24)
        {
            if (s[i] != '-')
                return FALSE;
        }
        else if (i == 37)
        {
            if (s[i] != '}')
                return FALSE;
        }
        else
        {
            if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0'))
                return FALSE;
        }
    }

    return TRUE;
}

/* Adapted from CLSIDFromString helper in dlls/ole32/compobj.c and
 * UuidFromString in dlls/rpcrt4/rpcrt4_main.c. */
static BOOL string_to_guid(LPCWSTR s, LPGUID id)
{
    /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */

    if (!validate_indices(s, 0, 8)) return FALSE;
    id->Data1 = (hex2bin[s[1]] << 28 | hex2bin[s[2]] << 24 | hex2bin[s[3]] << 20 | hex2bin[s[4]] << 16 |
                 hex2bin[s[5]] << 12 | hex2bin[s[6]] << 8  | hex2bin[s[7]] << 4  | hex2bin[s[8]]);
    if (!validate_indices(s, 9, 14)) return FALSE;
    id->Data2 = hex2bin[s[10]] << 12 | hex2bin[s[11]] << 8 | hex2bin[s[12]] << 4 | hex2bin[s[13]];
    if (!validate_indices(s, 15, 19)) return FALSE;
    id->Data3 = hex2bin[s[15]] << 12 | hex2bin[s[16]] << 8 | hex2bin[s[17]] << 4 | hex2bin[s[18]];

    /* these are just sequential bytes */

    if (!validate_indices(s, 20, 21)) return FALSE;
    id->Data4[0] = hex2bin[s[20]] << 4 | hex2bin[s[21]];
    if (!validate_indices(s, 22, 24)) return FALSE;
    id->Data4[1] = hex2bin[s[22]] << 4 | hex2bin[s[23]];

    if (!validate_indices(s, 25, 26)) return FALSE;
    id->Data4[2] = hex2bin[s[25]] << 4 | hex2bin[s[26]];
    if (!validate_indices(s, 27, 28)) return FALSE;
    id->Data4[3] = hex2bin[s[27]] << 4 | hex2bin[s[28]];
    if (!validate_indices(s, 29, 30)) return FALSE;
    id->Data4[4] = hex2bin[s[29]] << 4 | hex2bin[s[30]];
    if (!validate_indices(s, 31, 32)) return FALSE;
    id->Data4[5] = hex2bin[s[31]] << 4 | hex2bin[s[32]];
    if (!validate_indices(s, 33, 34)) return FALSE;
    id->Data4[6] = hex2bin[s[33]] << 4 | hex2bin[s[34]];
    if (!validate_indices(s, 35, 37)) return FALSE;
    id->Data4[7] = hex2bin[s[35]] << 4 | hex2bin[s[36]];

    return TRUE;
}

HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey)
{
    BOOL has_minus = FALSE, has_comma = FALSE;

    TRACE("(%s, %p)\n", debugstr_w(pszString), pkey);

    if (!pszString || !pkey)
        return E_POINTER;

    memset(pkey, 0, sizeof(PROPERTYKEY));

    if (!string_to_guid(pszString, &pkey->fmtid))
        return E_INVALIDARG;

    pszString += GUIDSTRING_MAX - 1;

    if (!*pszString)
        return E_INVALIDARG;

    /* Only the space seems to be recognized as whitespace. The comma is only
     * recognized once and processing terminates if another comma is found. */
    while (*pszString == ' ' || *pszString == ',')
    {
        if (*pszString == ',')
        {
            if (has_comma)
                return S_OK;
            else
                has_comma = TRUE;
        }
        pszString++;
    }

    if (!*pszString)
        return E_INVALIDARG;

    /* Only two minus signs are recognized if no comma is detected. The first
     * sign is ignored, and the second is interpreted. If a comma is detected
     * before the minus sign, then only one minus sign counts, and property ID
     * interpretation begins with the next character. */
    if (has_comma)
    {
        if (*pszString == '-')
        {
            has_minus = TRUE;
            pszString++;
        }
    }
    else
    {
        if (*pszString == '-')
            pszString++;

        /* Skip any intermediate spaces after the first minus sign. */
        while (*pszString == ' ')
            pszString++;

        if (*pszString == '-')
        {
            has_minus = TRUE;
            pszString++;
        }

        /* Skip any remaining spaces after minus sign. */
        while (*pszString == ' ')
            pszString++;
    }

    /* Overflow is not checked. */
    while (isdigitW(*pszString))
    {
        pkey->pid *= 10;
        pkey->pid += (*pszString - '0');
        pszString++;
    }

    if (has_minus)
        pkey->pid = ~pkey->pid + 1;

    return S_OK;
}
