/*
 *    INSENG Implementation
 *
 * Copyright 2006 Mike McCormack
 *
 * 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 "winuser.h"
#include "ole2.h"
#include "rpcproxy.h"
#include "initguid.h"
#include "inseng.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(inseng);

static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
{
    return HeapAlloc(GetProcessHeap(), 0, size);
}

static inline BOOL heap_free(void *mem)
{
    return HeapFree(GetProcessHeap(), 0, mem);
}

static HINSTANCE instance;

struct InstallEngine {
    IInstallEngine2 IInstallEngine2_iface;
    LONG ref;
};

static inline InstallEngine *impl_from_IInstallEngine2(IInstallEngine2 *iface)
{
    return CONTAINING_RECORD(iface, InstallEngine, IInstallEngine2_iface);
}

static HRESULT WINAPI InstallEngine_QueryInterface(IInstallEngine2 *iface, REFIID riid, void **ppv)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IInstallEngine2_iface;
    }else if(IsEqualGUID(&IID_IInstallEngine, riid)) {
        TRACE("(%p)->(IID_IInstallEngine %p)\n", This, ppv);
        *ppv = &This->IInstallEngine2_iface;
    }else if(IsEqualGUID(&IID_IInstallEngine2, riid)) {
        TRACE("(%p)->(IID_IInstallEngine2 %p)\n", This, ppv);
        *ppv = &This->IInstallEngine2_iface;
    }else {
        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI InstallEngine_AddRef(IInstallEngine2 *iface)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI InstallEngine_Release(IInstallEngine2 *iface)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref)
        heap_free(This);

    return ref;
}

static HRESULT WINAPI InstallEngine_GetEngineStatus(IInstallEngine2 *iface, DWORD *status)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%p)\n", This, status);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetCifFile(IInstallEngine2 *iface, const char *cab_name, const char *cif_name)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s %s)\n", This, debugstr_a(cab_name), debugstr_a(cif_name));
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_DownloadComponents(IInstallEngine2 *iface, DWORD flags)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%x)\n", This, flags);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_InstallComponents(IInstallEngine2 *iface, DWORD flags)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%x)\n", This, flags);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_EnumInstallIDs(IInstallEngine2 *iface, UINT index, char **id)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%d %p)\n", This, index, id);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_EnumDownloadIDs(IInstallEngine2 *iface, UINT index, char **id)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%d %p)\n", This, index, id);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_IsComponentInstalled(IInstallEngine2 *iface, const char *id, DWORD *status)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_a(id), status);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_RegisterInstallEngineCallback(IInstallEngine2 *iface, IInstallEngineCallback *callback)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%p)\n", This, callback);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_UnregisterInstallEngineCallback(IInstallEngine2 *iface)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetAction(IInstallEngine2 *iface, const char *id, DWORD action, DWORD priority)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s %d %d)\n", This, debugstr_a(id), action, priority);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_GetSizes(IInstallEngine2 *iface, const char *id, COMPONENT_SIZES *sizes)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_a(id), sizes);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_LaunchExtraCommand(IInstallEngine2 *iface, const char *inf_name, const char *section)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s %s)\n", This, debugstr_a(inf_name), debugstr_a(section));
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_GetDisplayName(IInstallEngine2 *iface, const char *id, const char *name)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s %s)\n", This, debugstr_a(id), debugstr_a(name));
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetBaseUrl(IInstallEngine2 *iface, const char *base_name)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_a(base_name));
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetDownloadDir(IInstallEngine2 *iface, const char *download_dir)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_a(download_dir));
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetInstallDrive(IInstallEngine2 *iface, char drive)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%c)\n", This, drive);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetInstallOptions(IInstallEngine2 *iface, DWORD flags)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%x)\n", This, flags);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetHWND(IInstallEngine2 *iface, HWND hwnd)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%p)\n", This, hwnd);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_SetIStream(IInstallEngine2 *iface, IStream *stream)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%p)\n", This, stream);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_Abort(IInstallEngine2 *iface, DWORD flags)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%x)\n", This, flags);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_Suspend(IInstallEngine2 *iface)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine_Resume(IInstallEngine2 *iface)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine2_SetLocalCif(IInstallEngine2 *iface, const char *cif)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_a(cif));
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallEngine2_GetICifFile(IInstallEngine2 *iface, ICifFile **cif_file)
{
    InstallEngine *This = impl_from_IInstallEngine2(iface);
    FIXME("(%p)->(%p)\n", This, cif_file);
    return E_NOTIMPL;
}

static const IInstallEngine2Vtbl InstallEngine2Vtbl = {
    InstallEngine_QueryInterface,
    InstallEngine_AddRef,
    InstallEngine_Release,
    InstallEngine_GetEngineStatus,
    InstallEngine_SetCifFile,
    InstallEngine_DownloadComponents,
    InstallEngine_InstallComponents,
    InstallEngine_EnumInstallIDs,
    InstallEngine_EnumDownloadIDs,
    InstallEngine_IsComponentInstalled,
    InstallEngine_RegisterInstallEngineCallback,
    InstallEngine_UnregisterInstallEngineCallback,
    InstallEngine_SetAction,
    InstallEngine_GetSizes,
    InstallEngine_LaunchExtraCommand,
    InstallEngine_GetDisplayName,
    InstallEngine_SetBaseUrl,
    InstallEngine_SetDownloadDir,
    InstallEngine_SetInstallDrive,
    InstallEngine_SetInstallOptions,
    InstallEngine_SetHWND,
    InstallEngine_SetIStream,
    InstallEngine_Abort,
    InstallEngine_Suspend,
    InstallEngine_Resume,
    InstallEngine2_SetLocalCif,
    InstallEngine2_GetICifFile
};

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)
{
    return 2;
}

static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
    return 1;
}

static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
{
    return S_OK;
}

static HRESULT WINAPI InstallEngineCF_CreateInstance(IClassFactory *iface, IUnknown *outer,
        REFIID riid, void **ppv)
{
    InstallEngine *engine;
    HRESULT hres;

    TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);

    engine = heap_alloc(sizeof(*engine));
    if(!engine)
        return E_OUTOFMEMORY;

    engine->IInstallEngine2_iface.lpVtbl = &InstallEngine2Vtbl;
    engine->ref = 1;

    hres = IInstallEngine2_QueryInterface(&engine->IInstallEngine2_iface, riid, ppv);
    IInstallEngine2_Release(&engine->IInstallEngine2_iface);
    return hres;
}

static const IClassFactoryVtbl InstallEngineCFVtbl = {
    ClassFactory_QueryInterface,
    ClassFactory_AddRef,
    ClassFactory_Release,
    InstallEngineCF_CreateInstance,
    ClassFactory_LockServer
};

static IClassFactory InstallEngineCF = { &InstallEngineCFVtbl };

BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
    switch(fdwReason)
    {
    case DLL_WINE_PREATTACH:
        return FALSE;  /* prefer native version */
    case DLL_PROCESS_ATTACH:
        instance = hInstDLL;
        DisableThreadLibraryCalls(hInstDLL);
        break;
    }
    return TRUE;
}

/***********************************************************************
 *             DllGetClassObject (INSENG.@)
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
    if(IsEqualGUID(rclsid, &CLSID_InstallEngine)) {
        TRACE("(CLSID_InstallEngine %s %p)\n", debugstr_guid(iid), ppv);
        return IClassFactory_QueryInterface(&InstallEngineCF, iid, ppv);
    }

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

/***********************************************************************
 *              DllCanUnloadNow (INSENG.@)
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_FALSE;
}

/***********************************************************************
 *		DllRegisterServer (INSENG.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    return __wine_register_resources( instance );
}

/***********************************************************************
 *		DllUnregisterServer (INSENG.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
    return __wine_unregister_resources( instance );
}

BOOL WINAPI CheckTrustEx( LPVOID a, LPVOID b, LPVOID c, LPVOID d, LPVOID e )
{
    FIXME("%p %p %p %p %p\n", a, b, c, d, e );
    return TRUE;
}

/***********************************************************************
 *  DllInstall (INSENG.@)
 */
HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
{
    FIXME("(%s, %s): stub\n", bInstall ? "TRUE" : "FALSE", debugstr_w(cmdline));
    return S_OK;
}
