/*
 * Copyright 2014 Andrew Eikum 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
 */

#include "config.h"

#include <stdarg.h>

#define COBJMACROS
#include "initguid.h"
#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "rpcproxy.h"
#include "shellapi.h"
#include "shlwapi.h"

#include "wine/debug.h"

#include "packager_classes.h"

WINE_DEFAULT_DEBUG_CHANNEL(packager);

static HINSTANCE g_instance;

struct Package {
    IOleObject IOleObject_iface;
    IPersistStorage IPersistStorage_iface;

    LONG ref;

    WCHAR filename[MAX_PATH];

    IOleClientSite *clientsite;
};

static inline struct Package *impl_from_IOleObject(IOleObject *iface)
{
    return CONTAINING_RECORD(iface, struct Package, IOleObject_iface);
}

static inline struct Package *impl_from_IPersistStorage(IPersistStorage *iface)
{
    return CONTAINING_RECORD(iface, struct Package, IPersistStorage_iface);
}

static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **obj)
{
    struct Package *This = impl_from_IOleObject(iface);

    if(IsEqualGUID(riid, &IID_IUnknown) ||
            IsEqualGUID(riid, &IID_IOleObject)) {
        TRACE("(%p)->(IID_IOleObject, %p)\n", This, obj);
        *obj = &This->IOleObject_iface;
    }else if(IsEqualGUID(riid, &IID_IPersistStorage)){
        TRACE("(%p)->(IID_IPersistStorage, %p)\n", This, obj);
        *obj = &This->IPersistStorage_iface;
    }else {
        FIXME("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
        *obj = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
{
    struct Package *This = impl_from_IOleObject(iface);
    LONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI OleObject_Release(IOleObject *iface)
{
    struct Package *This = impl_from_IOleObject(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref){
        if(This->clientsite)
            IOleClientSite_Release(This->clientsite);

        if(*This->filename)
            DeleteFileW(This->filename);

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

    return ref;
}

static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
{
    struct Package *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%p)\n", This, pClientSite);

    if(This->clientsite)
        IOleClientSite_Release(This->clientsite);

    This->clientsite = pClientSite;
    if(pClientSite)
        IOleClientSite_AddRef(pClientSite);

    return S_OK;
}

static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, ppClientSite);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%s, %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
{
    struct Package *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(0x%x)\n", This, dwSaveOption);

    if(dwSaveOption == OLECLOSE_SAVEIFDIRTY ||
            dwSaveOption == OLECLOSE_PROMPTSAVE)
        WARN("Saving unsupported\n");

    return S_OK;
}

static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d, %p)\n", This, dwWhichMoniker, pmk);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d, %d, %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
                                        DWORD dwReserved)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p, 0x%x, %d)\n", This, pDataObject, fCreation, dwReserved);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d, %p)\n", This, dwReserved, ppDataObject);
    return E_NOTIMPL;
}

static HRESULT do_activate_object(struct Package *This, HWND parent)
{
    static const WCHAR openW[] = {'o','p','e','n',0};
    ShellExecuteW(parent, openW, This->filename, NULL, NULL, SW_SHOW);
    return S_OK;
}

static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
                                        LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
    struct Package *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%d)\n", This, iVerb);

    switch(iVerb){
    case 0:
        return do_activate_object(This, hwndParent);
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Update(IOleObject *iface)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, pClsid);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d, %p)\n", This, dwFormOfType, pszUserType);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d, %p)\n", This, dwDrawAspect, psizel);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d, %p)\n", This, dwDrawAspect, psizel);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p, %p)\n", This, pAdvSink, pdwConnection);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d)\n", This, dwConnection);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, ppenumAdvise);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
{
    struct Package *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%d, %p)\n", This, dwAspect, pdwStatus);

    if(!pdwStatus)
        return E_INVALIDARG;

    *pdwStatus = OLEMISC_ONLYICONIC;

    return S_OK;
}

static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
{
    struct Package *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, pLogpal);
    return E_NOTIMPL;
}

static const IOleObjectVtbl OleObject_Vtbl = {
    OleObject_QueryInterface,
    OleObject_AddRef,
    OleObject_Release,
    OleObject_SetClientSite,
    OleObject_GetClientSite,
    OleObject_SetHostNames,
    OleObject_Close,
    OleObject_SetMoniker,
    OleObject_GetMoniker,
    OleObject_InitFromData,
    OleObject_GetClipboardData,
    OleObject_DoVerb,
    OleObject_EnumVerbs,
    OleObject_Update,
    OleObject_IsUpToDate,
    OleObject_GetUserClassID,
    OleObject_GetUserType,
    OleObject_SetExtent,
    OleObject_GetExtent,
    OleObject_Advise,
    OleObject_Unadvise,
    OleObject_EnumAdvise,
    OleObject_GetMiscStatus,
    OleObject_SetColorScheme
};

static HRESULT WINAPI PersistStorage_QueryInterface(IPersistStorage* iface,
        REFIID riid, void **ppvObject)
{
    struct Package *This = impl_from_IPersistStorage(iface);

    return OleObject_QueryInterface(&This->IOleObject_iface, riid, ppvObject);
}

static ULONG WINAPI PersistStorage_AddRef(IPersistStorage* iface)
{
    struct Package *This = impl_from_IPersistStorage(iface);

    return OleObject_AddRef(&This->IOleObject_iface);
}

static ULONG WINAPI PersistStorage_Release(IPersistStorage* iface)
{
    struct Package *This = impl_from_IPersistStorage(iface);

    return OleObject_Release(&This->IOleObject_iface);
}

static HRESULT WINAPI PersistStorage_GetClassID(IPersistStorage* iface,
        CLSID *pClassID)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    FIXME("(%p)->(%p)\n", This, pClassID);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStorage_IsDirty(IPersistStorage* iface)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStorage_InitNew(IPersistStorage* iface,
        IStorage *pStg)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    FIXME("(%p)->(%p)\n", This, pStg);
    return E_NOTIMPL;
}

static HRESULT discard_string(struct Package *This, IStream *stream)
{
    ULONG nbytes;
    HRESULT hr;
    char chr = 0;

    do{
        hr = IStream_Read(stream, &chr, 1, &nbytes);
        if(FAILED(hr) || !nbytes){
            TRACE("Unexpected end of stream or Read failed with %08x\n", hr);
            return (hr == S_OK || hr == S_FALSE) ? E_FAIL : hr;
        }
    }while(chr);

    return S_OK;
}

static HRESULT WINAPI PersistStorage_Load(IPersistStorage* iface,
        IStorage *pStg)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    IStream *stream;
    DWORD payload_size, len, stream_filename_len, filenameA_len, i, bytes_read;
    ULARGE_INTEGER payload_pos;
    LARGE_INTEGER seek;
    HRESULT hr;
    HANDLE file = INVALID_HANDLE_VALUE;
    WCHAR filenameW[MAX_PATH];
    char filenameA[MAX_PATH];
    WCHAR *stream_filename;
    WCHAR *base_end, extension[MAX_PATH];

    static const WCHAR ole10nativeW[] = {0x0001,'O','l','e','1','0','N','a','t','i','v','e',0};

    TRACE("(%p)->(%p)\n", This, pStg);

    hr = IStorage_OpenStream(pStg, ole10nativeW, NULL,
            STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
    if(FAILED(hr)){
        TRACE("OpenStream gave: %08x\n", hr);
        return hr;
    }

    /* skip stream size & two unknown bytes */
    seek.QuadPart = 6;
    hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
    if(FAILED(hr))
        goto exit;

    /* read and discard label */
    hr = discard_string(This, stream);
    if(FAILED(hr))
        goto exit;

    /* read and discard filename */
    hr = discard_string(This, stream);
    if(FAILED(hr))
        goto exit;

    /* skip more unknown data */
    seek.QuadPart = 4;
    hr = IStream_Seek(stream, seek, STREAM_SEEK_CUR, NULL);
    if(FAILED(hr))
        goto exit;

    /* ASCIIZ filename */
    hr = IStream_Read(stream, &filenameA_len, 4, NULL);
    if(FAILED(hr))
        goto exit;

    hr = IStream_Read(stream, filenameA, filenameA_len, NULL);
    if(FAILED(hr))
        goto exit;

    /* skip payload for now */
    hr = IStream_Read(stream, &payload_size, 4, NULL);
    if(FAILED(hr))
        goto exit;

    seek.QuadPart = 0;
    hr = IStream_Seek(stream, seek, STREAM_SEEK_CUR, &payload_pos);
    if(FAILED(hr))
        goto exit;

    seek.QuadPart = payload_size;
    hr = IStream_Seek(stream, seek, STREAM_SEEK_CUR, NULL);
    if(FAILED(hr))
        goto exit;

    /* read WCHAR filename, if present */
    hr = IStream_Read(stream, &len, 4, &bytes_read);
    if(SUCCEEDED(hr) && bytes_read == 4 && len > 0){
        hr = IStream_Read(stream, filenameW, len * sizeof(WCHAR), NULL);
        if(FAILED(hr))
            goto exit;
    }else{
        len = MultiByteToWideChar(CP_ACP, 0, filenameA, filenameA_len,
                filenameW, sizeof(filenameW) / sizeof(*filenameW));
    }

    stream_filename = filenameW + len - 1;
    while(stream_filename != filenameW &&
            *stream_filename != '\\')
        --stream_filename;
    if(*stream_filename == '\\')
        ++stream_filename;
    stream_filename_len = len - (stream_filename - filenameW);

    len = GetTempPathW(sizeof(This->filename)/sizeof(WCHAR), This->filename);
    memcpy(This->filename + len, stream_filename, stream_filename_len * sizeof(WCHAR));
    This->filename[len + stream_filename_len] = 0;

    /* read & write payload */
    memcpy(&seek, &payload_pos, sizeof(seek)); /* STREAM_SEEK_SET treats as ULARGE_INTEGER */
    hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
    if(FAILED(hr))
        goto exit;

    base_end = PathFindExtensionW(This->filename);
    lstrcpyW(extension, base_end);
    i = 1;

    file = CreateFileW(This->filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
            CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    while(file == INVALID_HANDLE_VALUE){
        static const WCHAR fmtW[] = {' ','(','%','u',')',0};

        if(GetLastError() != ERROR_FILE_EXISTS){
            WARN("CreateFile failed: %u\n", GetLastError());
            hr = E_FAIL;
            goto exit;
        }

        /* file exists, so increment file name and try again */
        ++i;
        wsprintfW(base_end, fmtW, i);
        lstrcatW(base_end, extension);

        file = CreateFileW(This->filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    }
    TRACE("Final filename: %s\n", wine_dbgstr_w(This->filename));

    while(payload_size){
        ULONG nbytes;
        BYTE data[4096];
        DWORD written;

        hr = IStream_Read(stream, data, min(sizeof(data), payload_size), &nbytes);
        if(FAILED(hr) || nbytes == 0){
            TRACE("Unexpected end of file, or Read failed with %08x\n", hr);
            if(hr == S_OK || hr == S_FALSE)
                hr = E_FAIL;
            goto exit;
        }

        payload_size -= nbytes;

        WriteFile(file, data, nbytes, &written, NULL);
    }

    hr = S_OK;

exit:
    if(file != INVALID_HANDLE_VALUE){
        CloseHandle(file);
        if(FAILED(hr))
            DeleteFileW(This->filename);
    }
    IStream_Release(stream);

    TRACE("Returning: %08x\n", hr);
    return hr;
}

static HRESULT WINAPI PersistStorage_Save(IPersistStorage* iface,
        IStorage *pStgSave, BOOL fSameAsLoad)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    FIXME("(%p)->(%p, %u)\n", This, pStgSave, fSameAsLoad);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStorage_SaveCompleted(IPersistStorage* iface,
        IStorage *pStgNew)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    FIXME("(%p)->(%p)\n", This, pStgNew);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStorage_HandsOffStorage(IPersistStorage* iface)
{
    struct Package *This = impl_from_IPersistStorage(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static IPersistStorageVtbl PersistStorage_Vtbl = {
    PersistStorage_QueryInterface,
    PersistStorage_AddRef,
    PersistStorage_Release,
    PersistStorage_GetClassID,
    PersistStorage_IsDirty,
    PersistStorage_InitNew,
    PersistStorage_Load,
    PersistStorage_Save,
    PersistStorage_SaveCompleted,
    PersistStorage_HandsOffStorage
};

static HRESULT WINAPI PackageCF_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
{
    TRACE("(static)->(%s, %p)\n", debugstr_guid(riid), obj);

    if(IsEqualGUID(&IID_IUnknown, riid) ||
            IsEqualGUID(&IID_IClassFactory, riid))
        *obj = iface;
    else
        *obj = NULL;

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

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

static ULONG WINAPI PackageCF_AddRef(IClassFactory *iface)
{
    TRACE("(static)\n");
    return 2;
}

static ULONG WINAPI PackageCF_Release(IClassFactory *iface)
{
    TRACE("(static)\n");
    return 1;
}

static HRESULT WINAPI PackageCF_CreateInstance(IClassFactory *iface, IUnknown *outer,
        REFIID iid, void **obj)
{
    struct Package *package;

    TRACE("(static)->(%p, %s, %p)\n", outer, wine_dbgstr_guid(iid), obj);

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

    package->IOleObject_iface.lpVtbl = &OleObject_Vtbl;
    package->IPersistStorage_iface.lpVtbl = &PersistStorage_Vtbl;

    return IOleObject_QueryInterface(&package->IOleObject_iface, iid, obj);
}

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

static const IClassFactoryVtbl PackageCF_Vtbl = {
    PackageCF_QueryInterface,
    PackageCF_AddRef,
    PackageCF_Release,
    PackageCF_CreateInstance,
    PackageCF_LockServer
};

static IClassFactory PackageCF = {
    &PackageCF_Vtbl
};

HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
{
    TRACE("(%s, %s, %p)\n", wine_dbgstr_guid(clsid), wine_dbgstr_guid(iid), obj);

    if(IsEqualGUID(clsid, &CLSID_Package))
        return IClassFactory_QueryInterface(&PackageCF, iid, obj);

    FIXME("Unknown CLSID: %s\n", wine_dbgstr_guid(clsid));

    return CLASS_E_CLASSNOTAVAILABLE;
}

HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_OK;
}

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

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

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
    TRACE("(%p, %u, %p)\n", instance, reason, reserved);

    switch(reason){
        case DLL_PROCESS_ATTACH:
            g_instance = instance;
            DisableThreadLibraryCalls(instance);
            break;
    }

    return TRUE;
}
