/*
 *  ITfCompartmentMgr implementation
 *
 *  Copyright 2009 Aric Stewart, 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>

#define COBJMACROS

#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "shlwapi.h"
#include "winerror.h"
#include "objbase.h"
#include "oleauto.h"
#include "olectl.h"

#include "wine/unicode.h"

#include "msctf.h"
#include "msctf_internal.h"

WINE_DEFAULT_DEBUG_CHANNEL(msctf);

typedef struct tagCompartmentValue {
    struct list entry;
    GUID guid;
    TfClientId owner;
    ITfCompartment *compartment;
} CompartmentValue;

typedef struct tagCompartmentMgr {
    ITfCompartmentMgr ITfCompartmentMgr_iface;
    LONG refCount;

    IUnknown *pUnkOuter;

    struct list values;
} CompartmentMgr;

typedef struct tagCompartmentEnumGuid {
    IEnumGUID IEnumGUID_iface;
    LONG refCount;

    struct list *values;
    struct list *cursor;
} CompartmentEnumGuid;

typedef struct tagCompartment {
    ITfCompartment ITfCompartment_iface;
    ITfSource ITfSource_iface;
    LONG refCount;

    /* Only VT_I4, VT_UNKNOWN and VT_BSTR data types are allowed */
    VARIANT variant;
    CompartmentValue *valueData;
    struct list CompartmentEventSink;
} Compartment;

static HRESULT CompartmentEnumGuid_Constructor(struct list* values, IEnumGUID **ppOut);
static HRESULT Compartment_Constructor(CompartmentValue *value, ITfCompartment **ppOut);

static inline CompartmentMgr *impl_from_ITfCompartmentMgr(ITfCompartmentMgr *iface)
{
    return CONTAINING_RECORD(iface, CompartmentMgr, ITfCompartmentMgr_iface);
}

static inline Compartment *impl_from_ITfCompartment(ITfCompartment *iface)
{
    return CONTAINING_RECORD(iface, Compartment, ITfCompartment_iface);
}

static inline Compartment *impl_from_ITfSource(ITfSource *iface)
{
    return CONTAINING_RECORD(iface, Compartment, ITfSource_iface);
}

static inline CompartmentEnumGuid *impl_from_IEnumGUID(IEnumGUID *iface)
{
    return CONTAINING_RECORD(iface, CompartmentEnumGuid, IEnumGUID_iface);
}

HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);
    struct list *cursor, *cursor2;

    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->values)
    {
        CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
        list_remove(cursor);
        ITfCompartment_Release(value->compartment);
        HeapFree(GetProcessHeap(),0,value);
    }

    HeapFree(GetProcessHeap(),0,This);
    return S_OK;
}

/*****************************************************
 * ITfCompartmentMgr functions
 *****************************************************/
static HRESULT WINAPI CompartmentMgr_QueryInterface(ITfCompartmentMgr *iface, REFIID iid, LPVOID *ppvOut)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);
    if (This->pUnkOuter)
        return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvOut);
    else
    {
        *ppvOut = NULL;

        if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartmentMgr))
        {
            *ppvOut = &This->ITfCompartmentMgr_iface;
        }

        if (*ppvOut)
        {
            ITfCompartmentMgr_AddRef(iface);
            return S_OK;
        }

        WARN("unsupported interface: %s\n", debugstr_guid(iid));
        return E_NOINTERFACE;
    }
}

static ULONG WINAPI CompartmentMgr_AddRef(ITfCompartmentMgr *iface)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);
    if (This->pUnkOuter)
        return IUnknown_AddRef(This->pUnkOuter);
    else
        return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI CompartmentMgr_Release(ITfCompartmentMgr *iface)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);
    if (This->pUnkOuter)
        return IUnknown_Release(This->pUnkOuter);
    else
    {
        ULONG ret;

        ret = InterlockedDecrement(&This->refCount);
        if (ret == 0)
            CompartmentMgr_Destructor(iface);
        return ret;
    }
}

static HRESULT WINAPI CompartmentMgr_GetCompartment(ITfCompartmentMgr *iface,
        REFGUID rguid, ITfCompartment **ppcomp)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);
    CompartmentValue* value;
    struct list *cursor;
    HRESULT hr;

    TRACE("(%p) %s  %p\n",This,debugstr_guid(rguid),ppcomp);

    LIST_FOR_EACH(cursor, &This->values)
    {
        value = LIST_ENTRY(cursor,CompartmentValue,entry);
        if (IsEqualGUID(rguid,&value->guid))
        {
            ITfCompartment_AddRef(value->compartment);
            *ppcomp = value->compartment;
            return S_OK;
        }
    }

    value = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentValue));
    value->guid = *rguid;
    value->owner = 0;
    hr = Compartment_Constructor(value,&value->compartment);
    if (SUCCEEDED(hr))
    {
        list_add_head(&This->values,&value->entry);
        ITfCompartment_AddRef(value->compartment);
        *ppcomp = value->compartment;
    }
    else
    {
        HeapFree(GetProcessHeap(),0,value);
        *ppcomp = NULL;
    }
    return hr;
}

static HRESULT WINAPI CompartmentMgr_ClearCompartment(ITfCompartmentMgr *iface,
    TfClientId tid, REFGUID rguid)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);
    struct list *cursor;

    TRACE("(%p) %i %s\n",This,tid,debugstr_guid(rguid));

    LIST_FOR_EACH(cursor, &This->values)
    {
        CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
        if (IsEqualGUID(rguid,&value->guid))
        {
            if (value->owner && tid != value->owner)
                return E_UNEXPECTED;
            list_remove(cursor);
            ITfCompartment_Release(value->compartment);
            HeapFree(GetProcessHeap(),0,value);
            return S_OK;
        }
    }

    return CONNECT_E_NOCONNECTION;
}

static HRESULT WINAPI CompartmentMgr_EnumCompartments(ITfCompartmentMgr *iface,
 IEnumGUID **ppEnum)
{
    CompartmentMgr *This = impl_from_ITfCompartmentMgr(iface);

    TRACE("(%p) %p\n",This,ppEnum);
    if (!ppEnum)
        return E_INVALIDARG;
    return CompartmentEnumGuid_Constructor(&This->values, ppEnum);
}

static const ITfCompartmentMgrVtbl CompartmentMgrVtbl =
{
    CompartmentMgr_QueryInterface,
    CompartmentMgr_AddRef,
    CompartmentMgr_Release,
    CompartmentMgr_GetCompartment,
    CompartmentMgr_ClearCompartment,
    CompartmentMgr_EnumCompartments
};

HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
{
    CompartmentMgr *This;

    if (!ppOut)
        return E_POINTER;

    if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
        return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentMgr));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->ITfCompartmentMgr_iface.lpVtbl = &CompartmentMgrVtbl;
    This->pUnkOuter = pUnkOuter;
    list_init(&This->values);

    if (pUnkOuter)
    {
        *ppOut = (IUnknown*)&This->ITfCompartmentMgr_iface;
        TRACE("returning %p\n", *ppOut);
        return S_OK;
    }
    else
    {
        HRESULT hr;
        hr = ITfCompartmentMgr_QueryInterface(&This->ITfCompartmentMgr_iface, riid, (void**)ppOut);
        if (FAILED(hr))
            HeapFree(GetProcessHeap(),0,This);
        return hr;
    }
}

/**************************************************
 * IEnumGUID implementation for ITfCompartmentMgr::EnumCompartments
 **************************************************/
static void CompartmentEnumGuid_Destructor(CompartmentEnumGuid *This)
{
    TRACE("destroying %p\n", This);
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI CompartmentEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
    {
        *ppvOut = &This->IEnumGUID_iface;
    }

    if (*ppvOut)
    {
        IEnumGUID_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI CompartmentEnumGuid_AddRef(IEnumGUID *iface)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI CompartmentEnumGuid_Release(IEnumGUID *iface)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        CompartmentEnumGuid_Destructor(This);
    return ret;
}

/*****************************************************
 * IEnumGuid functions
 *****************************************************/
static HRESULT WINAPI CompartmentEnumGuid_Next(IEnumGUID *iface,
    ULONG celt, GUID *rgelt, ULONG *pceltFetched)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    ULONG fetched = 0;

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

    if (rgelt == NULL) return E_POINTER;

    while (fetched < celt && This->cursor)
    {
        CompartmentValue* value = LIST_ENTRY(This->cursor,CompartmentValue,entry);
        if (!value)
            break;

        This->cursor = list_next(This->values,This->cursor);
        *rgelt = value->guid;

        ++fetched;
        ++rgelt;
    }

    if (pceltFetched) *pceltFetched = fetched;
    return fetched == celt ? S_OK : S_FALSE;
}

static HRESULT WINAPI CompartmentEnumGuid_Skip(IEnumGUID *iface, ULONG celt)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    TRACE("(%p)\n",This);

    This->cursor = list_next(This->values,This->cursor);
    return S_OK;
}

static HRESULT WINAPI CompartmentEnumGuid_Reset(IEnumGUID *iface)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    TRACE("(%p)\n",This);
    This->cursor = list_head(This->values);
    return S_OK;
}

static HRESULT WINAPI CompartmentEnumGuid_Clone(IEnumGUID *iface,
    IEnumGUID **ppenum)
{
    CompartmentEnumGuid *This = impl_from_IEnumGUID(iface);
    HRESULT res;

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

    if (ppenum == NULL) return E_POINTER;

    res = CompartmentEnumGuid_Constructor(This->values, ppenum);
    if (SUCCEEDED(res))
    {
        CompartmentEnumGuid *new_This = impl_from_IEnumGUID(*ppenum);
        new_This->cursor = This->cursor;
    }
    return res;
}

static const IEnumGUIDVtbl EnumGUIDVtbl =
{
    CompartmentEnumGuid_QueryInterface,
    CompartmentEnumGuid_AddRef,
    CompartmentEnumGuid_Release,
    CompartmentEnumGuid_Next,
    CompartmentEnumGuid_Skip,
    CompartmentEnumGuid_Reset,
    CompartmentEnumGuid_Clone
};

static HRESULT CompartmentEnumGuid_Constructor(struct list *values, IEnumGUID **ppOut)
{
    CompartmentEnumGuid *This;

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentEnumGuid));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->IEnumGUID_iface.lpVtbl= &EnumGUIDVtbl;
    This->refCount = 1;

    This->values = values;
    This->cursor = list_head(values);

    *ppOut = &This->IEnumGUID_iface;
    TRACE("returning %p\n", *ppOut);
    return S_OK;
}

/**************************************************
 * ITfCompartment
 **************************************************/
static void Compartment_Destructor(Compartment *This)
{
    TRACE("destroying %p\n", This);
    VariantClear(&This->variant);
    free_sinks(&This->CompartmentEventSink);
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI Compartment_QueryInterface(ITfCompartment *iface, REFIID iid, LPVOID *ppvOut)
{
    Compartment *This = impl_from_ITfCompartment(iface);

    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartment))
    {
        *ppvOut = &This->ITfCompartment_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfSource))
    {
        *ppvOut = &This->ITfSource_iface;
    }

    if (*ppvOut)
    {
        ITfCompartment_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI Compartment_AddRef(ITfCompartment *iface)
{
    Compartment *This = impl_from_ITfCompartment(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI Compartment_Release(ITfCompartment *iface)
{
    Compartment *This = impl_from_ITfCompartment(iface);
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        Compartment_Destructor(This);
    return ret;
}

static HRESULT WINAPI Compartment_SetValue(ITfCompartment *iface,
    TfClientId tid, const VARIANT *pvarValue)
{
    Compartment *This = impl_from_ITfCompartment(iface);
    ITfCompartmentEventSink *sink;
    struct list *cursor;

    TRACE("(%p) %i %p\n",This,tid,pvarValue);

    if (!pvarValue)
        return E_INVALIDARG;

    if (!(V_VT(pvarValue) == VT_BSTR || V_VT(pvarValue) == VT_I4 ||
          V_VT(pvarValue) == VT_UNKNOWN))
        return E_INVALIDARG;

    if (!This->valueData->owner)
        This->valueData->owner = tid;

    VariantClear(&This->variant);

    /* Shallow copy of value and type */
    This->variant = *pvarValue;

    if (V_VT(pvarValue) == VT_BSTR)
        V_BSTR(&This->variant) = SysAllocStringByteLen((char*)V_BSTR(pvarValue),
                SysStringByteLen(V_BSTR(pvarValue)));
    else if (V_VT(pvarValue) == VT_UNKNOWN)
        IUnknown_AddRef(V_UNKNOWN(&This->variant));

    SINK_FOR_EACH(cursor, &This->CompartmentEventSink, ITfCompartmentEventSink, sink)
    {
        ITfCompartmentEventSink_OnChange(sink, &This->valueData->guid);
    }

    return S_OK;
}

static HRESULT WINAPI Compartment_GetValue(ITfCompartment *iface,
    VARIANT *pvarValue)
{
    Compartment *This = impl_from_ITfCompartment(iface);
    TRACE("(%p) %p\n",This, pvarValue);

    if (!pvarValue)
        return E_INVALIDARG;

    VariantInit(pvarValue);
    if (V_VT(&This->variant) == VT_EMPTY) return S_FALSE;
    return VariantCopy(pvarValue,&This->variant);
}

static const ITfCompartmentVtbl CompartmentVtbl =
{
    Compartment_QueryInterface,
    Compartment_AddRef,
    Compartment_Release,
    Compartment_SetValue,
    Compartment_GetValue
};

/*****************************************************
 * ITfSource functions
 *****************************************************/

static HRESULT WINAPI CompartmentSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
{
    Compartment *This = impl_from_ITfSource(iface);
    return ITfCompartment_QueryInterface(&This->ITfCompartment_iface, iid, ppvOut);
}

static ULONG WINAPI CompartmentSource_AddRef(ITfSource *iface)
{
    Compartment *This = impl_from_ITfSource(iface);
    return ITfCompartment_AddRef(&This->ITfCompartment_iface);
}

static ULONG WINAPI CompartmentSource_Release(ITfSource *iface)
{
    Compartment *This = impl_from_ITfSource(iface);
    return ITfCompartment_Release(&This->ITfCompartment_iface);
}

static HRESULT WINAPI CompartmentSource_AdviseSink(ITfSource *iface,
        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
{
    Compartment *This = impl_from_ITfSource(iface);

    TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);

    if (!riid || !punk || !pdwCookie)
        return E_INVALIDARG;

    if (IsEqualIID(riid, &IID_ITfCompartmentEventSink))
        return advise_sink(&This->CompartmentEventSink, &IID_ITfCompartmentEventSink,
                           COOKIE_MAGIC_COMPARTMENTSINK, punk, pdwCookie);

    FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
    return E_NOTIMPL;
}

static HRESULT WINAPI CompartmentSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
{
    Compartment *This = impl_from_ITfSource(iface);

    TRACE("(%p) %x\n",This,pdwCookie);

    if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_COMPARTMENTSINK)
        return E_INVALIDARG;

    return unadvise_sink(pdwCookie);
}

static const ITfSourceVtbl CompartmentSourceVtbl =
{
    CompartmentSource_QueryInterface,
    CompartmentSource_AddRef,
    CompartmentSource_Release,
    CompartmentSource_AdviseSink,
    CompartmentSource_UnadviseSink,
};

static HRESULT Compartment_Constructor(CompartmentValue *valueData, ITfCompartment **ppOut)
{
    Compartment *This;

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Compartment));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->ITfCompartment_iface.lpVtbl= &CompartmentVtbl;
    This->ITfSource_iface.lpVtbl = &CompartmentSourceVtbl;
    This->refCount = 1;

    This->valueData = valueData;
    VariantInit(&This->variant);

    list_init(&This->CompartmentEventSink);

    *ppOut = &This->ITfCompartment_iface;
    TRACE("returning %p\n", *ppOut);
    return S_OK;
}
