/*
 *    ITSS Moniker implementation
 *
 * Copyright 2004 Mike McCormack
 *
 *  Implementation of the infamous mk:@MSITStore moniker
 *
 * 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>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "wine/itss.h"
#include "wine/unicode.h"
#include "wine/debug.h"

#include "itsstor.h"

WINE_DEFAULT_DEBUG_CHANNEL(itss);

/*****************************************************************************/

typedef struct {
    IMoniker IMoniker_iface;
    LONG ref;
    LPWSTR szHtml;
    WCHAR szFile[1];
} ITS_IMonikerImpl;

static inline ITS_IMonikerImpl *impl_from_IMoniker(IMoniker *iface)
{
    return CONTAINING_RECORD(iface, ITS_IMonikerImpl, IMoniker_iface);
}

/*** IUnknown methods ***/
static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
    IMoniker* iface,
    REFIID riid,
    void** ppvObject)
{
    ITS_IMonikerImpl *This = impl_from_IMoniker(iface);

    if (IsEqualGUID(riid, &IID_IUnknown)
	|| IsEqualGUID(riid, &IID_IParseDisplayName))
    {
	IClassFactory_AddRef(iface);
	*ppvObject = This;
	return S_OK;
    }

    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI ITS_IMonikerImpl_AddRef(
    IMoniker* iface)
{
    ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
    TRACE("%p\n", This);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI ITS_IMonikerImpl_Release(
    IMoniker* iface)
{
    ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0) {
        HeapFree(GetProcessHeap(), 0, This);
        ITSS_UnlockModule();
    }

    return ref;
}

/*** IPersist methods ***/
static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
    IMoniker* iface,
    CLSID* pClassID)
{
    ITS_IMonikerImpl *This = impl_from_IMoniker(iface);

    TRACE("%p %p\n", This, pClassID);
    *pClassID = CLSID_ITStorage;
    return S_OK;
}

/*** IPersistStream methods ***/
static HRESULT WINAPI ITS_IMonikerImpl_IsDirty(
    IMoniker* iface)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_Load(
    IMoniker* iface,
    IStream* pStm)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_Save(
    IMoniker* iface,
    IStream* pStm,
    BOOL fClearDirty)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_GetSizeMax(
    IMoniker* iface,
    ULARGE_INTEGER* pcbSize)
{
    FIXME("\n");
    return E_NOTIMPL;
}

/*** IMoniker methods ***/
static HRESULT WINAPI ITS_IMonikerImpl_BindToObject(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    REFIID riidResult,
    void** ppvResult)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    REFIID riid,
    void** ppvObj)
{
    ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
    DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
    HRESULT r;
    IStorage *stg = NULL;

    TRACE("%p %p %p %s %p\n", This,
           pbc, pmkToLeft, debugstr_guid(riid), ppvObj);

    r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
    if( r == S_OK )
    {
        TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
        if (IsEqualGUID(riid, &IID_IStream))
            r = IStorage_OpenStream( stg, This->szHtml,
                       NULL, grfMode, 0, (IStream**)ppvObj );
        else if (IsEqualGUID(riid, &IID_IStorage))
            r = IStorage_OpenStorage( stg, This->szHtml,
                       NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
        else
            r = STG_E_ACCESSDENIED;
        IStorage_Release( stg );
    }

    return r;
}

static HRESULT WINAPI ITS_IMonikerImpl_Reduce(
    IMoniker* iface,
    IBindCtx* pbc,
    DWORD dwReduceHowFar,
    IMoniker** ppmkToLeft,
    IMoniker** ppmkReduced)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_ComposeWith(
    IMoniker* iface,
    IMoniker* pmkRight,
    BOOL fOnlyIfNotGeneric,
    IMoniker** ppmkComposite)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_Enum(
    IMoniker* iface,
    BOOL fForward,
    IEnumMoniker** ppenumMoniker)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_IsEqual(
    IMoniker* iface,
    IMoniker* pmkOtherMoniker)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_Hash(
    IMoniker* iface,
    DWORD* pdwHash)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_IsRunning(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    IMoniker* pmkNewlyRunning)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_GetTimeOfLastChange(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    FILETIME* pFileTime)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_Inverse(
    IMoniker* iface,
    IMoniker** ppmk)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_CommonPrefixWith(
    IMoniker* iface,
    IMoniker* pmkOther,
    IMoniker** ppmkPrefix)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_RelativePathTo(
    IMoniker* iface,
    IMoniker* pmkOther,
    IMoniker** ppmkRelPath)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_GetDisplayName(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    LPOLESTR* ppszDisplayName)
{
    ITS_IMonikerImpl *This = impl_from_IMoniker(iface);
    static const WCHAR szFormat[] = {
        'm','s','-','i','t','s',':','%','s',':',':','%','s',0 };
    DWORD len = sizeof szFormat / sizeof(WCHAR);
    LPWSTR str;

    TRACE("%p %p %p %p\n", iface, pbc, pmkToLeft, ppszDisplayName);

    len = strlenW( This->szFile ) + strlenW( This->szHtml );
    str = CoTaskMemAlloc( len*sizeof(WCHAR) );
    sprintfW( str, szFormat, This->szFile, This->szHtml );

    *ppszDisplayName = str;
    
    return S_OK;
}

static HRESULT WINAPI ITS_IMonikerImpl_ParseDisplayName(
    IMoniker* iface,
    IBindCtx* pbc,
    IMoniker* pmkToLeft,
    LPOLESTR pszDisplayName,
    ULONG* pchEaten,
    IMoniker** ppmkOut)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITS_IMonikerImpl_IsSystemMoniker(
    IMoniker* iface,
    DWORD* pdwMksys)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const IMonikerVtbl ITS_IMonikerImpl_Vtbl =
{
    ITS_IMonikerImpl_QueryInterface,
    ITS_IMonikerImpl_AddRef,
    ITS_IMonikerImpl_Release,
    ITS_IMonikerImpl_GetClassID,
    ITS_IMonikerImpl_IsDirty,
    ITS_IMonikerImpl_Load,
    ITS_IMonikerImpl_Save,
    ITS_IMonikerImpl_GetSizeMax,
    ITS_IMonikerImpl_BindToObject,
    ITS_IMonikerImpl_BindToStorage,
    ITS_IMonikerImpl_Reduce,
    ITS_IMonikerImpl_ComposeWith,
    ITS_IMonikerImpl_Enum,
    ITS_IMonikerImpl_IsEqual,
    ITS_IMonikerImpl_Hash,
    ITS_IMonikerImpl_IsRunning,
    ITS_IMonikerImpl_GetTimeOfLastChange,
    ITS_IMonikerImpl_Inverse,
    ITS_IMonikerImpl_CommonPrefixWith,
    ITS_IMonikerImpl_RelativePathTo,
    ITS_IMonikerImpl_GetDisplayName,
    ITS_IMonikerImpl_ParseDisplayName,
    ITS_IMonikerImpl_IsSystemMoniker
};

static HRESULT ITS_IMoniker_create( IMoniker **ppObj, LPCWSTR name, DWORD n )
{
    ITS_IMonikerImpl *itsmon;
    DWORD sz;

    /* szFile[1] has space for one character already */
    sz = sizeof(ITS_IMonikerImpl) + strlenW( name )*sizeof(WCHAR);

    itsmon = HeapAlloc( GetProcessHeap(), 0, sz );
    itsmon->IMoniker_iface.lpVtbl = &ITS_IMonikerImpl_Vtbl;
    itsmon->ref = 1;
    strcpyW( itsmon->szFile, name );
    itsmon->szHtml = &itsmon->szFile[n];

    while( *itsmon->szHtml == ':' )
        *itsmon->szHtml++ = 0;

    TRACE("-> %p %s %s\n", itsmon,
          debugstr_w(itsmon->szFile), debugstr_w(itsmon->szHtml) );
    *ppObj = &itsmon->IMoniker_iface;

    ITSS_LockModule();
    return S_OK;
}

/*****************************************************************************/

typedef struct {
    IParseDisplayName IParseDisplayName_iface;
    LONG ref;
} ITS_IParseDisplayNameImpl;

static inline ITS_IParseDisplayNameImpl *impl_from_IParseDisplayName(IParseDisplayName *iface)
{
    return CONTAINING_RECORD(iface, ITS_IParseDisplayNameImpl, IParseDisplayName_iface);
}

static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
    IParseDisplayName* iface,
    REFIID riid,
    void** ppvObject)
{
    ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);

    if (IsEqualGUID(riid, &IID_IUnknown)
	|| IsEqualGUID(riid, &IID_IParseDisplayName))
    {
	IClassFactory_AddRef(iface);
	*ppvObject = This;
	return S_OK;
    }

    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI ITS_IParseDisplayNameImpl_AddRef(
    IParseDisplayName* iface)
{
    ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
    TRACE("%p\n", This);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
    IParseDisplayName* iface)
{
    ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0) {
        HeapFree(GetProcessHeap(), 0, This);
        ITSS_UnlockModule();
    }

    return ref;
}

static HRESULT WINAPI ITS_IParseDisplayNameImpl_ParseDisplayName(
    IParseDisplayName *iface,
    IBindCtx * pbc,
    LPOLESTR pszDisplayName, 
    ULONG * pchEaten,
    IMoniker ** ppmkOut)
{
    static const WCHAR szPrefix[] = { 
        '@','M','S','I','T','S','t','o','r','e',':',0 };
    const DWORD prefix_len = (sizeof szPrefix/sizeof szPrefix[0])-1;
    DWORD n;

    ITS_IParseDisplayNameImpl *This = impl_from_IParseDisplayName(iface);

    TRACE("%p %s %p %p\n", This,
          debugstr_w( pszDisplayName ), pchEaten, ppmkOut );

    if( strncmpW( pszDisplayName, szPrefix, prefix_len ) )
        return MK_E_SYNTAX;

    /* search backwards for a double colon */
    for( n = strlenW( pszDisplayName ) - 3; prefix_len <= n; n-- )
        if( ( pszDisplayName[n] == ':' ) && ( pszDisplayName[n+1] == ':' ) )
            break;

    if( n < prefix_len )
        return MK_E_SYNTAX;

    if( !pszDisplayName[n+2] )
        return MK_E_SYNTAX;

    *pchEaten = strlenW( pszDisplayName ) - n - 3;

    return ITS_IMoniker_create( ppmkOut,
              &pszDisplayName[prefix_len], n-prefix_len );
}

static const IParseDisplayNameVtbl ITS_IParseDisplayNameImpl_Vtbl =
{
    ITS_IParseDisplayNameImpl_QueryInterface,
    ITS_IParseDisplayNameImpl_AddRef,
    ITS_IParseDisplayNameImpl_Release,
    ITS_IParseDisplayNameImpl_ParseDisplayName
};
 
HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
    ITS_IParseDisplayNameImpl *its;

    if( pUnkOuter )
        return CLASS_E_NOAGGREGATION;

    its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
    its->IParseDisplayName_iface.lpVtbl = &ITS_IParseDisplayNameImpl_Vtbl;
    its->ref = 1;

    TRACE("-> %p\n", its);
    *ppObj = its;

    ITSS_LockModule();
    return S_OK;
}
