/*
 * Tests for marshaling IDispatchEx
 *
 * Copyright 2005-2006 Robert Shearman
 * Copyright 2010 Huw Davies
 *
 * 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
#define CONST_VTABLE

#include <stdarg.h>

#include "initguid.h"
#include "objidl.h"
#include "dispex.h"

#include "wine/test.h"

#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", (unsigned long int)hr)

#define RELEASEMARSHALDATA WM_USER

struct host_object_data
{
    IStream *stream;
    IID iid;
    IUnknown *object;
    MSHLFLAGS marshal_flags;
    HANDLE marshal_event;
    HANDLE error_event;
    IMessageFilter *filter;
};

static DWORD CALLBACK host_object_proc(LPVOID p)
{
    struct host_object_data *data = p;
    HRESULT hr;
    MSG msg;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    if (data->filter)
    {
        IMessageFilter * prev_filter = NULL;
        hr = CoRegisterMessageFilter(data->filter, &prev_filter);
        if (prev_filter) IMessageFilter_Release(prev_filter);
        ok_ole_success(hr, CoRegisterMessageFilter);
    }

    hr = CoMarshalInterface(data->stream, &data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags);

    /* force the message queue to be created before signaling parent thread */
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

    if(hr == S_OK)
        SetEvent(data->marshal_event);
    else
    {
        win_skip("IDispatchEx marshaller not available.\n");
        SetEvent(data->error_event);
        return hr;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
        {
            trace("releasing marshal data\n");
            CoReleaseMarshalData(data->stream);
            SetEvent((HANDLE)msg.lParam);
        }
        else
            DispatchMessage(&msg);
    }

    HeapFree(GetProcessHeap(), 0, data);

    CoUninitialize();

    return hr;
}

static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread)
{
    DWORD tid = 0, ret;
    HANDLE events[2];
    struct host_object_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));

    data->stream = stream;
    data->iid = *riid;
    data->object = object;
    data->marshal_flags = marshal_flags;
    data->marshal_event = events[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
    data->error_event   = events[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
    data->filter = filter;

    *thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid);

    /* wait for marshaling to complete before returning */
    ret = WaitForMultipleObjects(2, events, FALSE, INFINITE);
    CloseHandle(events[0]);
    CloseHandle(events[1]);

    if(ret == WAIT_OBJECT_0) return tid;

    WaitForSingleObject(*thread, INFINITE);
    CloseHandle(*thread);
    *thread = INVALID_HANDLE_VALUE;
    return 0;
}

static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread)
{
    return start_host_object2(stream, riid, object, marshal_flags, NULL, thread);
}

static void end_host_object(DWORD tid, HANDLE thread)
{
    BOOL ret = PostThreadMessage(tid, WM_QUIT, 0, 0);
    ok(ret, "PostThreadMessage failed with error %d\n", GetLastError());
    /* be careful of races - don't return until hosting thread has terminated */
    WaitForSingleObject(thread, INFINITE);
    CloseHandle(thread);
}

typedef struct
{
    IDispatchEx IDispatchEx_iface;
    LONG refs;
} dispex;

static inline dispex *impl_from_IDispatchEx(IDispatchEx *iface)
{
    return CONTAINING_RECORD(iface, dispex, IDispatchEx_iface);
}

static HRESULT WINAPI dispex_QueryInterface(IDispatchEx* iface,
                                            REFIID iid,  void **obj)
{
    trace("QI {%08x-...}\n", iid->Data1);
    if(IsEqualIID(iid, &IID_IUnknown) ||
       IsEqualIID(iid, &IID_IDispatchEx))
    {
        IDispatchEx_AddRef(iface);
        *obj = iface;
        return S_OK;
    }
    else
    {
        *obj = NULL;
        return E_NOINTERFACE;
    }
}

static ULONG WINAPI dispex_AddRef(IDispatchEx* iface)
{
    dispex *This = impl_from_IDispatchEx(iface);
    trace("AddRef\n");

    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI dispex_Release(IDispatchEx* iface)
{
    dispex *This = impl_from_IDispatchEx(iface);
    ULONG refs = InterlockedDecrement(&This->refs);
    trace("Release\n");
    if(!refs)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refs;
}

 static HRESULT WINAPI dispex_GetTypeInfoCount(IDispatchEx* iface,
                                               UINT *pctinfo)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetTypeInfo(IDispatchEx* iface,
                                         UINT iTInfo,
                                         LCID lcid,
                                         ITypeInfo **ppTInfo)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetIDsOfNames(IDispatchEx* iface,
                                           REFIID riid,
                                           LPOLESTR *rgszNames,
                                           UINT cNames,
                                           LCID lcid,
                                           DISPID *rgDispId)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_Invoke(IDispatchEx* iface,
                                    DISPID dispIdMember,
                                    REFIID riid,
                                    LCID lcid,
                                    WORD wFlags,
                                    DISPPARAMS *pDispParams,
                                    VARIANT *pVarResult,
                                    EXCEPINFO *pExcepInfo,
                                    UINT *puArgErr)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetDispID(IDispatchEx* iface,
                                       BSTR bstrName,
                                       DWORD grfdex,
                                       DISPID *pid)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI defer_fn(EXCEPINFO *except)
{
    except->scode = E_OUTOFMEMORY;
    return S_OK;
}

static HRESULT WINAPI dispex_InvokeEx(IDispatchEx* iface,
                                      DISPID id,
                                      LCID lcid,
                                      WORD wFlags,
                                      DISPPARAMS *pdp,
                                      VARIANT *pvarRes,
                                      EXCEPINFO *pei,
                                      IServiceProvider *pspCaller)
{
    if(id == 1)
    {
        ok(pdp->cArgs == 0, "got %d\n", pdp->cArgs);
        ok(pei == NULL, "got non-NULL excepinfo\n");
        ok(pvarRes == NULL, "got non-NULL result\n");
    }
    else if(id == 2)
    {
        ok(pdp->cArgs == 2, "got %d\n", pdp->cArgs);
        ok(V_VT(&pdp->rgvarg[0]) == VT_INT, "got %04x\n", V_VT(&pdp->rgvarg[0]));
        ok(V_VT(&pdp->rgvarg[1]) == (VT_INT | VT_BYREF), "got %04x\n", V_VT(&pdp->rgvarg[1]));
        ok(*V_INTREF(&pdp->rgvarg[1]) == 0xbeef, "got %08x\n", *V_INTREF(&pdp->rgvarg[1]));
        *V_INTREF(&pdp->rgvarg[1]) = 0xdead;
    }
    else if(id == 3)
    {
        ok(pdp->cArgs == 2, "got %d\n", pdp->cArgs);
        ok(V_VT(&pdp->rgvarg[0]) == VT_INT, "got %04x\n", V_VT(&pdp->rgvarg[0]));
        ok(V_VT(&pdp->rgvarg[1]) == (VT_INT | VT_BYREF), "got %04x\n", V_VT(&pdp->rgvarg[1]));
        V_VT(&pdp->rgvarg[0]) = VT_I4;
    }
    else if(id == 4)
    {
        ok(wFlags == 0xf, "got %04x\n", wFlags);
    }
    else if(id == 5)
    {
        if(pei) pei->pfnDeferredFillIn = defer_fn;
        return DISP_E_EXCEPTION;
    }
    return S_OK;
}

static HRESULT WINAPI dispex_DeleteMemberByName(IDispatchEx* iface,
                                                BSTR bstrName,
                                                DWORD grfdex)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_DeleteMemberByDispID(IDispatchEx* iface, DISPID id)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetMemberProperties(IDispatchEx* iface, DISPID id,
                                                 DWORD grfdexFetch, DWORD *pgrfdex)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetMemberName(IDispatchEx* iface,
                                           DISPID id, BSTR *pbstrName)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetNextDispID(IDispatchEx* iface,
                                           DWORD grfdex,
                                           DISPID id,
                                           DISPID *pid)
{
    trace("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dispex_GetNameSpaceParent(IDispatchEx* iface,
                                                IUnknown **ppunk)
{
    trace("\n");
    return E_NOTIMPL;
}

static const IDispatchExVtbl dispex_vtable =
{
    dispex_QueryInterface,
    dispex_AddRef,
    dispex_Release,
    dispex_GetTypeInfoCount,
    dispex_GetTypeInfo,
    dispex_GetIDsOfNames,
    dispex_Invoke,
    dispex_GetDispID,
    dispex_InvokeEx,
    dispex_DeleteMemberByName,
    dispex_DeleteMemberByDispID,
    dispex_GetMemberProperties,
    dispex_GetMemberName,
    dispex_GetNextDispID,
    dispex_GetNameSpaceParent
};

static IDispatchEx *dispex_create(void)
{
    dispex *This;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This) return NULL;
    This->IDispatchEx_iface.lpVtbl = &dispex_vtable;
    This->refs = 1;
    return (IDispatchEx *)This;
}

static void test_dispex(void)
{
    HRESULT hr;
    IStream *stream;
    DWORD tid;
    HANDLE thread;
    static const LARGE_INTEGER zero;
    IDispatchEx *dispex = dispex_create();
    DISPPARAMS params;
    VARIANTARG args[10];
    INT i;
    EXCEPINFO excepinfo;

    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
    ok(hr == S_OK, "got %08x\n", hr);
    tid = start_host_object(stream, &IID_IDispatchEx, (IUnknown *)dispex, MSHLFLAGS_NORMAL, &thread);
    IDispatchEx_Release(dispex);
    if(tid == 0)
    {
        IStream_Release(stream);
        return;
    }

    IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
    hr = CoUnmarshalInterface(stream, &IID_IDispatchEx, (void **)&dispex);
    ok(hr == S_OK, "got %08x\n", hr);
    IStream_Release(stream);

    params.rgvarg = NULL;
    params.rgdispidNamedArgs = NULL;
    params.cArgs = 0;
    params.cNamedArgs = 0;
    hr = IDispatchEx_InvokeEx(dispex, 1, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
    ok(hr == S_OK, "got %08x\n", hr);

    params.rgvarg = args;
    params.rgdispidNamedArgs = NULL;
    params.cArgs = 2;
    params.cNamedArgs = 0;
    V_VT(&args[0]) = VT_INT;
    V_INT(&args[0]) = 0xcafe;
    V_VT(&args[1]) = VT_INT | VT_BYREF;
    V_INTREF(&args[1]) = &i;
    i = 0xbeef;
    hr = IDispatchEx_InvokeEx(dispex, 2, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
    ok(hr == S_OK, "got %08x\n", hr);
    ok(i == 0xdead, "got %08x\n", i);

    /* change one of the argument vts */
    i = 0xbeef;
    hr = IDispatchEx_InvokeEx(dispex, 3, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
    ok(hr == DISP_E_BADCALLEE, "got %08x\n", hr);

    hr = IDispatchEx_InvokeEx(dispex, 4, LOCALE_SYSTEM_DEFAULT, 0xffff, &params, NULL, NULL, NULL);
    ok(hr == S_OK, "got %08x\n", hr);

    params.cArgs = 0;
    hr = IDispatchEx_InvokeEx(dispex, 5, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
    ok(hr == DISP_E_EXCEPTION, "got %08x\n", hr);
    hr = IDispatchEx_InvokeEx(dispex, 5, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, &excepinfo, NULL);
    ok(hr == DISP_E_EXCEPTION, "got %08x\n", hr);
    ok(excepinfo.scode == E_OUTOFMEMORY, "got scode %08x\n", excepinfo.scode);
    ok(excepinfo.pfnDeferredFillIn == NULL, "got non-NULL pfnDeferredFillIn\n");

    IDispatchEx_Release(dispex);
    end_host_object(tid, thread);
}

START_TEST(marshal)
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    test_dispex();

    CoUninitialize();
}
