/*
 * XML Document implementation
 *
 * Copyright 2007 James Hawkins
 *
 * 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>
#ifdef HAVE_LIBXML2
# include <libxml/parser.h>
# include <libxml/xmlerror.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "msxml6.h"
#include "wininet.h"
#include "winreg.h"
#include "shlwapi.h"
#include "ocidl.h"

#include "wine/debug.h"

#include "msxml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

#ifdef HAVE_LIBXML2

/* FIXME: IXMLDocument needs to implement
 *   - IXMLError
 *   - IPersistMoniker
 */

typedef struct _xmldoc
{
    IXMLDocument IXMLDocument_iface;
    IPersistStreamInit IPersistStreamInit_iface;
    LONG ref;
    HRESULT error;

    /* IXMLDocument */
    xmlDocPtr xmldoc;

    /* IPersistStream */
    IStream *stream;
} xmldoc;

static inline xmldoc *impl_from_IXMLDocument(IXMLDocument *iface)
{
    return CONTAINING_RECORD(iface, xmldoc, IXMLDocument_iface);
}

static inline xmldoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
{
    return CONTAINING_RECORD(iface, xmldoc, IPersistStreamInit_iface);
}

static HRESULT WINAPI xmldoc_QueryInterface(IXMLDocument *iface, REFIID riid, void** ppvObject)
{
    xmldoc *This = impl_from_IXMLDocument(iface);

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

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IXMLDocument) ||
        IsEqualGUID(riid, &IID_IXMLDOMDocument))
    {
        *ppvObject = iface;
    }
    else if (IsEqualGUID(&IID_IPersistStreamInit, riid) ||
             IsEqualGUID(&IID_IPersistStream, riid))
    {
        *ppvObject = &This->IPersistStreamInit_iface;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    IXMLDocument_AddRef(iface);

    return S_OK;
}

static ULONG WINAPI xmldoc_AddRef(IXMLDocument *iface)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    TRACE("%p\n", This);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI xmldoc_Release(IXMLDocument *iface)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    LONG ref;

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

    ref = InterlockedDecrement(&This->ref);
    if (ref == 0)
    {
        xmlFreeDoc(This->xmldoc);
        if (This->stream) IStream_Release(This->stream);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI xmldoc_GetTypeInfoCount(IXMLDocument *iface, UINT* pctinfo)
{
    xmldoc *This = impl_from_IXMLDocument(iface);

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

    *pctinfo = 1;

    return S_OK;
}

static HRESULT WINAPI xmldoc_GetTypeInfo(IXMLDocument *iface, UINT iTInfo,
                                         LCID lcid, ITypeInfo** ppTInfo)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    HRESULT hr;

    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(IXMLDocument_tid, ppTInfo);

    return hr;
}

static HRESULT WINAPI xmldoc_GetIDsOfNames(IXMLDocument *iface, REFIID riid,
                                           LPOLESTR* rgszNames, UINT cNames,
                                           LCID lcid, DISPID* rgDispId)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
          lcid, rgDispId);

    if(!rgszNames || cNames == 0 || !rgDispId)
        return E_INVALIDARG;

    hr = get_typeinfo(IXMLDocument_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI xmldoc_Invoke(IXMLDocument *iface, DISPID dispIdMember,
                                    REFIID riid, LCID lcid, WORD wFlags,
                                    DISPPARAMS* pDispParams, VARIANT* pVarResult,
                                    EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
          lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IXMLDocument_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDocument_iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI xmldoc_get_root(IXMLDocument *iface, IXMLElement **p)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    xmlNodePtr root;

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

    if (!p)
        return E_INVALIDARG;

    *p = NULL;

    if (!(root = xmlDocGetRootElement(This->xmldoc)))
        return E_FAIL;

    return XMLElement_create((IUnknown *)This, root, (LPVOID *)p, FALSE);
}

static HRESULT WINAPI xmldoc_get_fileSize(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_put_fileModifiedDate(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_get_fileUpdatedDate(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_get_URL(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

typedef struct {
    IBindStatusCallback IBindStatusCallback_iface;
} bsc;

static HRESULT WINAPI bsc_QueryInterface(
    IBindStatusCallback *iface,
    REFIID riid,
    LPVOID *ppobj )
{
    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IBindStatusCallback))
    {
        IBindStatusCallback_AddRef( iface );
        *ppobj = iface;
        return S_OK;
    }

    TRACE("interface %s not implemented\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI bsc_AddRef(
    IBindStatusCallback *iface )
{
    return 2;
}

static ULONG WINAPI bsc_Release(
    IBindStatusCallback *iface )
{
    return 1;
}

static HRESULT WINAPI bsc_OnStartBinding(
        IBindStatusCallback* iface,
        DWORD dwReserved,
        IBinding* pib)
{
    return S_OK;
}

static HRESULT WINAPI bsc_GetPriority(
        IBindStatusCallback* iface,
        LONG* pnPriority)
{
    return S_OK;
}

static HRESULT WINAPI bsc_OnLowResource(
        IBindStatusCallback* iface,
        DWORD reserved)
{
    return S_OK;
}

static HRESULT WINAPI bsc_OnProgress(
        IBindStatusCallback* iface,
        ULONG ulProgress,
        ULONG ulProgressMax,
        ULONG ulStatusCode,
        LPCWSTR szStatusText)
{
    return S_OK;
}

static HRESULT WINAPI bsc_OnStopBinding(
        IBindStatusCallback* iface,
        HRESULT hresult,
        LPCWSTR szError)
{
    return S_OK;
}

static HRESULT WINAPI bsc_GetBindInfo(
        IBindStatusCallback* iface,
        DWORD* grfBINDF,
        BINDINFO* pbindinfo)
{
    *grfBINDF = BINDF_RESYNCHRONIZE;

    return S_OK;
}

static HRESULT WINAPI bsc_OnDataAvailable(
        IBindStatusCallback* iface,
        DWORD grfBSCF,
        DWORD dwSize,
        FORMATETC* pformatetc,
        STGMEDIUM* pstgmed)
{
    return S_OK;
}

static HRESULT WINAPI bsc_OnObjectAvailable(
        IBindStatusCallback* iface,
        REFIID riid,
        IUnknown* punk)
{
    return S_OK;
}

static const struct IBindStatusCallbackVtbl bsc_vtbl =
{
    bsc_QueryInterface,
    bsc_AddRef,
    bsc_Release,
    bsc_OnStartBinding,
    bsc_GetPriority,
    bsc_OnLowResource,
    bsc_OnProgress,
    bsc_OnStopBinding,
    bsc_GetBindInfo,
    bsc_OnDataAvailable,
    bsc_OnObjectAvailable
};

static bsc xmldoc_bsc = { { &bsc_vtbl } };

static HRESULT WINAPI xmldoc_put_URL(IXMLDocument *iface, BSTR p)
{
    WCHAR url[INTERNET_MAX_URL_LENGTH];
    IStream *stream;
    IBindCtx *bctx;
    IMoniker *moniker;
    IPersistStreamInit *persist;
    HRESULT hr;

    TRACE("(%p, %s)\n", iface, debugstr_w(p));

    if (!p)
        return E_INVALIDARG;

    if (!PathIsURLW(p))
    {
        WCHAR fullpath[MAX_PATH];
        DWORD needed = sizeof(url) / sizeof(WCHAR);

        if (!PathSearchAndQualifyW(p, fullpath, sizeof(fullpath) / sizeof(WCHAR)))
        {
            ERR("can't find path\n");
            return E_FAIL;
        }

        if (FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
        {
            ERR("can't create url from path\n");
            return E_FAIL;
        }

        p = url;
    }

    hr = CreateURLMoniker(NULL, p, &moniker);
    if (FAILED(hr))
        return hr;

    CreateAsyncBindCtx(0, &xmldoc_bsc.IBindStatusCallback_iface, 0, &bctx);

    hr = IMoniker_BindToStorage(moniker, bctx, NULL, &IID_IStream, (LPVOID *)&stream);
    IBindCtx_Release(bctx);
    IMoniker_Release(moniker);
    if (FAILED(hr))
        return hr;

    hr = IXMLDocument_QueryInterface(iface, &IID_IPersistStreamInit, (LPVOID *)&persist);
    if (FAILED(hr))
    {
        IStream_Release(stream);
        return hr;
    }

    hr = IPersistStreamInit_Load(persist, stream);
    IPersistStreamInit_Release(persist);
    IStream_Release(stream);

    return hr;
}

static HRESULT WINAPI xmldoc_get_mimeType(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_get_readyState(IXMLDocument *iface, LONG *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_get_charset(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_put_charset(IXMLDocument *iface, BSTR p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_get_version(IXMLDocument *iface, BSTR *p)
{
    xmldoc *This = impl_from_IXMLDocument(iface);

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

    if (!p) return E_INVALIDARG;
    *p = bstr_from_xmlChar(This->xmldoc->version);

    return S_OK;
}

static HRESULT WINAPI xmldoc_get_doctype(IXMLDocument *iface, BSTR *p)
{
    xmldoc *This = impl_from_IXMLDocument(iface);
    xmlDtd *dtd;

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

    if (!p) return E_INVALIDARG;

    dtd = xmlGetIntSubset(This->xmldoc);
    if (!dtd) return S_FALSE;

    *p = bstr_from_xmlChar(dtd->name);
    CharUpperBuffW(*p, SysStringLen(*p));

    return S_OK;
}

static HRESULT WINAPI xmldoc_get_dtdURl(IXMLDocument *iface, BSTR *p)
{
    FIXME("(%p, %p): stub\n", iface, p);
    return E_NOTIMPL;
}

static xmlElementType type_msxml_to_libxml(LONG type)
{
    switch (type)
    {
        case XMLELEMTYPE_ELEMENT:
            return XML_ELEMENT_NODE;
        case XMLELEMTYPE_TEXT:
            return XML_TEXT_NODE;
        case XMLELEMTYPE_COMMENT:
            return XML_COMMENT_NODE;
        case XMLELEMTYPE_DOCUMENT:
            return XML_DOCUMENT_NODE;
        case XMLELEMTYPE_DTD:
            return XML_DTD_NODE;
        case XMLELEMTYPE_PI:
            return XML_PI_NODE;
        default:
            break;
    }

    return -1; /* FIXME: what is OTHER in msxml? */
}

static HRESULT WINAPI xmldoc_createElement(IXMLDocument *iface, VARIANT vType,
                                           VARIANT var1, IXMLElement **ppElem)
{
    xmlNodePtr node;
    static const xmlChar empty[] = "\0";

    TRACE("(%p)->(%s %s %p)\n", iface, debugstr_variant(&vType),
        debugstr_variant(&var1), ppElem);

    if (!ppElem)
        return E_INVALIDARG;

    *ppElem = NULL;

    if (V_VT(&vType) != VT_I4)
        return E_INVALIDARG;

    if(type_msxml_to_libxml(V_I4(&vType)) == -1)
        return E_NOTIMPL;

    node = xmlNewNode(NULL, empty);
    node->type = type_msxml_to_libxml(V_I4(&vType));

    /* FIXME: create xmlNodePtr based on vType and var1 */
    return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem, TRUE);
}

static const struct IXMLDocumentVtbl xmldoc_vtbl =
{
    xmldoc_QueryInterface,
    xmldoc_AddRef,
    xmldoc_Release,
    xmldoc_GetTypeInfoCount,
    xmldoc_GetTypeInfo,
    xmldoc_GetIDsOfNames,
    xmldoc_Invoke,
    xmldoc_get_root,
    xmldoc_get_fileSize,
    xmldoc_put_fileModifiedDate,
    xmldoc_get_fileUpdatedDate,
    xmldoc_get_URL,
    xmldoc_put_URL,
    xmldoc_get_mimeType,
    xmldoc_get_readyState,
    xmldoc_get_charset,
    xmldoc_put_charset,
    xmldoc_get_version,
    xmldoc_get_doctype,
    xmldoc_get_dtdURl,
    xmldoc_createElement
};

/************************************************************************
 * xmldoc implementation of IPersistStreamInit.
 */
static HRESULT WINAPI xmldoc_IPersistStreamInit_QueryInterface(
    IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj)
{
    xmldoc *this = impl_from_IPersistStreamInit(iface);
    return IXMLDocument_QueryInterface(&this->IXMLDocument_iface, riid, ppvObj);
}

static ULONG WINAPI xmldoc_IPersistStreamInit_AddRef(
    IPersistStreamInit *iface)
{
    xmldoc *this = impl_from_IPersistStreamInit(iface);
    return IXMLDocument_AddRef(&this->IXMLDocument_iface);
}

static ULONG WINAPI xmldoc_IPersistStreamInit_Release(
    IPersistStreamInit *iface)
{
    xmldoc *this = impl_from_IPersistStreamInit(iface);
    return IXMLDocument_Release(&this->IXMLDocument_iface);
}

static HRESULT WINAPI xmldoc_IPersistStreamInit_GetClassID(
    IPersistStreamInit *iface, CLSID *classid)
{
    xmldoc *this = impl_from_IPersistStreamInit(iface);
    TRACE("(%p,%p)\n", this, classid);

    if (!classid) return E_POINTER;

    *classid = CLSID_XMLDocument;
    return S_OK;
}

static HRESULT WINAPI xmldoc_IPersistStreamInit_IsDirty(
    IPersistStreamInit *iface)
{
    FIXME("(%p): stub!\n", iface);
    return E_NOTIMPL;
}

static xmlDocPtr parse_xml(char *ptr, int len)
{
#ifdef HAVE_XMLREADMEMORY
    return xmlReadMemory(ptr, len, NULL, NULL,
                         XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS);
#else
    return xmlParseMemory(ptr, len);
#endif
}

static HRESULT WINAPI xmldoc_IPersistStreamInit_Load(
    IPersistStreamInit *iface, LPSTREAM pStm)
{
    xmldoc *This = impl_from_IPersistStreamInit(iface);
    HRESULT hr;
    HGLOBAL hglobal;
    DWORD read, written, len;
    BYTE buf[4096];
    char *ptr;

    TRACE("(%p, %p)\n", iface, pStm);

    if (!pStm)
        return E_INVALIDARG;

    /* release previously allocated stream */
    if (This->stream) IStream_Release(This->stream);
    hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
    if (FAILED(hr))
        return hr;

    do
    {
        IStream_Read(pStm, buf, sizeof(buf), &read);
        hr = IStream_Write(This->stream, buf, read, &written);
    } while(SUCCEEDED(hr) && written != 0 && read != 0);

    if (FAILED(hr))
    {
        ERR("Failed to copy stream\n");
        return hr;
    }

    hr = GetHGlobalFromStream(This->stream, &hglobal);
    if (FAILED(hr))
        return hr;

    len = GlobalSize(hglobal);
    ptr = GlobalLock(hglobal);
    if (len != 0)
    {
        xmlFreeDoc(This->xmldoc);
        This->xmldoc = parse_xml(ptr, len);
    }
    GlobalUnlock(hglobal);

    if (!This->xmldoc)
    {
        ERR("Failed to parse xml\n");
        return E_FAIL;
    }

    return S_OK;
}

static HRESULT WINAPI xmldoc_IPersistStreamInit_Save(
    IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty)
{
    FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_IPersistStreamInit_GetSizeMax(
    IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
{
    xmldoc *This = impl_from_IPersistStreamInit(iface);
    TRACE("(%p, %p)\n", This, pcbSize);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmldoc_IPersistStreamInit_InitNew(
    IPersistStreamInit *iface)
{
    xmldoc *This = impl_from_IPersistStreamInit(iface);
    TRACE("(%p)\n", This);
    return S_OK;
}

static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
{
  xmldoc_IPersistStreamInit_QueryInterface,
  xmldoc_IPersistStreamInit_AddRef,
  xmldoc_IPersistStreamInit_Release,
  xmldoc_IPersistStreamInit_GetClassID,
  xmldoc_IPersistStreamInit_IsDirty,
  xmldoc_IPersistStreamInit_Load,
  xmldoc_IPersistStreamInit_Save,
  xmldoc_IPersistStreamInit_GetSizeMax,
  xmldoc_IPersistStreamInit_InitNew
};

HRESULT XMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
    xmldoc *doc;

    TRACE("(%p,%p)\n", pUnkOuter, ppObj);

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

    doc->IXMLDocument_iface.lpVtbl = &xmldoc_vtbl;
    doc->IPersistStreamInit_iface.lpVtbl = &xmldoc_IPersistStreamInit_VTable;
    doc->ref = 1;
    doc->error = S_OK;
    doc->xmldoc = NULL;
    doc->stream = NULL;

    *ppObj = &doc->IXMLDocument_iface;

    TRACE("returning iface %p\n", *ppObj);
    return S_OK;
}

#else

HRESULT XMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
    MESSAGE("This program tried to use an XMLDocument object, but\n"
            "libxml2 support was not present at compile time.\n");
    return E_NOTIMPL;
}

#endif
