/*
 * standard IPropertyStore implementation
 *
 * Copyright 2012 Vincent Povirk 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
 */

#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 "wine/list.h"

#include "initguid.h"
#include "propsys_private.h"

DEFINE_GUID(FMTID_NamedProperties, 0xd5cdd505, 0x2e9c, 0x101b, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae);

WINE_DEFAULT_DEBUG_CHANNEL(propsys);

typedef struct {
    struct list entry;
    DWORD pid;
    PROPVARIANT propvar;
    PSC_STATE state;
} propstore_value;

typedef struct {
    struct list entry;
    GUID fmtid;
    struct list values; /* list of struct propstore_value */
    DWORD count;
} propstore_format;

typedef struct {
    IPropertyStoreCache IPropertyStoreCache_iface;
    LONG ref;
    CRITICAL_SECTION lock;
    struct list formats; /* list of struct propstore_format */
} PropertyStore;

static inline PropertyStore *impl_from_IPropertyStoreCache(IPropertyStoreCache *iface)
{
    return CONTAINING_RECORD(iface, PropertyStore, IPropertyStoreCache_iface);
}

static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, REFIID iid,
    void **ppv)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IPropertyStore, iid) ||
        IsEqualIID(&IID_IPropertyStoreCache, iid))
    {
        *ppv = &This->IPropertyStoreCache_iface;
    }
    else
    {
        FIXME("No interface for %s\n", debugstr_guid(iid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI PropertyStore_AddRef(IPropertyStoreCache *iface)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static void destroy_format(propstore_format *format)
{
    propstore_value *cursor, *cursor2;
    LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &format->values, propstore_value, entry)
    {
        PropVariantClear(&cursor->propvar);
        HeapFree(GetProcessHeap(), 0, cursor);
    }
    HeapFree(GetProcessHeap(), 0, format);
}

static ULONG WINAPI PropertyStore_Release(IPropertyStoreCache *iface)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        propstore_format *cursor, *cursor2;
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->formats, propstore_format, entry)
            destroy_format(cursor);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI PropertyStore_GetCount(IPropertyStoreCache *iface,
    DWORD *cProps)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_format *format;

    TRACE("%p,%p\n", iface, cProps);

    if (!cProps)
        return E_POINTER;

    *cProps = 0;

    EnterCriticalSection(&This->lock);

    LIST_FOR_EACH_ENTRY(format, &This->formats, propstore_format, entry)
        *cProps += format->count;

    LeaveCriticalSection(&This->lock);

    return S_OK;
}

static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface,
    DWORD iProp, PROPERTYKEY *pkey)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_format *format=NULL, *format_candidate;
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%d,%p\n", iface, iProp, pkey);

    if (!pkey)
        return E_POINTER;

    EnterCriticalSection(&This->lock);

    LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
    {
        if (format_candidate->count > iProp)
        {
            format = format_candidate;
            pkey->fmtid = format->fmtid;
            break;
        }

        iProp -= format_candidate->count;
    }

    if (format)
    {
        LIST_FOR_EACH_ENTRY(value, &format->values, propstore_value, entry)
        {
            if (iProp == 0)
            {
                pkey->pid = value->pid;
                break;
            }

            iProp--;
        }

        hr = S_OK;
    }
    else
        hr = E_INVALIDARG;

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT PropertyStore_LookupValue(PropertyStore *This, REFPROPERTYKEY key,
    int insert, propstore_value **result)
{
    propstore_format *format=NULL, *format_candidate;
    propstore_value *value=NULL, *value_candidate;

    if (IsEqualGUID(&key->fmtid, &FMTID_NamedProperties))
    {
        /* This is used in the property store format [MS-PROPSTORE]
         * for named values and probably gets special treatment. */
        ERR("don't know how to handle FMTID_NamedProperties\n");
        return E_FAIL;
    }

    LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
    {
        if (IsEqualGUID(&format_candidate->fmtid, &key->fmtid))
        {
            format = format_candidate;
            break;
        }
    }

    if (!format)
    {
        if (!insert)
            return TYPE_E_ELEMENTNOTFOUND;

        format = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*format));
        if (!format)
            return E_OUTOFMEMORY;

        format->fmtid = key->fmtid;
        list_init(&format->values);
        list_add_tail(&This->formats, &format->entry);
    }

    LIST_FOR_EACH_ENTRY(value_candidate, &format->values, propstore_value, entry)
    {
        if (value_candidate->pid == key->pid)
        {
            value = value_candidate;
            break;
        }
    }

    if (!value)
    {
        if (!insert)
            return TYPE_E_ELEMENTNOTFOUND;

        value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*value));
        if (!value)
            return E_OUTOFMEMORY;

        value->pid = key->pid;
        list_add_tail(&format->values, &value->entry);
        format->count++;
    }

    *result = value;

    return S_OK;
}

static HRESULT WINAPI PropertyStore_GetValue(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PROPVARIANT *pv)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%p\n", iface, key, pv);

    if (!pv)
        return E_POINTER;

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, 0, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(pv, &value->propvar);
    else if (hr == TYPE_E_ELEMENTNOTFOUND)
    {
        PropVariantInit(pv);
        hr = S_OK;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI PropertyStore_SetValue(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, REFPROPVARIANT propvar)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;
    PROPVARIANT temp;

    TRACE("%p,%p,%p\n", iface, key, propvar);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, 1, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(&temp, propvar);

    if (SUCCEEDED(hr))
    {
        PropVariantClear(&value->propvar);
        value->propvar = temp;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI PropertyStore_Commit(IPropertyStoreCache *iface)
{
    FIXME("%p: stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI PropertyStore_GetState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PSC_STATE *pstate)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%p\n", iface, key, pstate);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, 0, &value);

    if (SUCCEEDED(hr))
        *pstate = value->state;

    LeaveCriticalSection(&This->lock);

    if (FAILED(hr))
        *pstate = PSC_NORMAL;

    return hr;
}

static HRESULT WINAPI PropertyStore_GetValueAndState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PROPVARIANT *ppropvar, PSC_STATE *pstate)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%p,%p\n", iface, key, ppropvar, pstate);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, 0, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(ppropvar, &value->propvar);

    if (SUCCEEDED(hr))
        *pstate = value->state;

    LeaveCriticalSection(&This->lock);

    if (FAILED(hr))
    {
        PropVariantInit(ppropvar);
        *pstate = PSC_NORMAL;
    }

    return hr;
}

static HRESULT WINAPI PropertyStore_SetState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PSC_STATE pstate)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%d\n", iface, key, pstate);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, 0, &value);

    if (SUCCEEDED(hr))
        value->state = pstate;

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI PropertyStore_SetValueAndState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, const PROPVARIANT *ppropvar, PSC_STATE state)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;
    PROPVARIANT temp;

    TRACE("%p,%p,%p,%d\n", iface, key, ppropvar, state);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, 1, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(&temp, ppropvar);

    if (SUCCEEDED(hr))
    {
        PropVariantClear(&value->propvar);
        value->propvar = temp;
        value->state = state;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static const IPropertyStoreCacheVtbl PropertyStore_Vtbl = {
    PropertyStore_QueryInterface,
    PropertyStore_AddRef,
    PropertyStore_Release,
    PropertyStore_GetCount,
    PropertyStore_GetAt,
    PropertyStore_GetValue,
    PropertyStore_SetValue,
    PropertyStore_Commit,
    PropertyStore_GetState,
    PropertyStore_GetValueAndState,
    PropertyStore_SetState,
    PropertyStore_SetValueAndState
};

HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    PropertyStore *This;
    HRESULT ret;

    TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);

    *ppv = NULL;

    if (pUnkOuter) return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyStore));
    if (!This) return E_OUTOFMEMORY;

    This->IPropertyStoreCache_iface.lpVtbl = &PropertyStore_Vtbl;
    This->ref = 1;
    InitializeCriticalSection(&This->lock);
    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStore.lock");
    list_init(&This->formats);

    ret = IPropertyStoreCache_QueryInterface(&This->IPropertyStoreCache_iface, iid, ppv);
    IPropertyStoreCache_Release(&This->IPropertyStoreCache_iface);

    return ret;
}
