/*
 * XML Parser implementation
 *
 * Copyright 2011 Alistair Leslie-Hughes
 *
 * 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>
# include <libxml/HTMLtree.h>
#endif

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

#include "msxml_private.h"

#include "initguid.h"
#include "xmlparser.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

typedef struct _xmlparser
{
    IXMLParser IXMLParser_iface;
    IXMLNodeFactory *nodefactory;
    IUnknown *input;
    LONG ref;

    int flags;
} xmlparser;

static inline xmlparser *impl_from_IXMLParser( IXMLParser *iface )
{
    return CONTAINING_RECORD(iface, xmlparser, IXMLParser_iface);
}

/*** IUnknown methods ***/
static HRESULT WINAPI xmlparser_QueryInterface(IXMLParser* iface, REFIID riid, void **ppvObject)
{
    xmlparser *This = impl_from_IXMLParser( iface );
    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);

    if ( IsEqualGUID( riid, &IID_IXMLParser ) ||
         IsEqualGUID( riid, &IID_IXMLNodeSource ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = iface;
    }
    else
    {
        TRACE("Unsupported interface %s\n", debugstr_guid(riid));
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    IXMLParser_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI xmlparser_AddRef(IXMLParser* iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );
    ULONG ref = InterlockedIncrement( &This->ref );
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI xmlparser_Release(IXMLParser* iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );
    ULONG ref = InterlockedDecrement( &This->ref );

    TRACE("(%p)->(%d)\n", This, ref);
    if ( ref == 0 )
    {
        if(This->input)
            IUnknown_Release(This->input);

        if(This->nodefactory)
            IXMLNodeFactory_Release(This->nodefactory);

        heap_free( This );
    }

    return ref;
}

/*** IXMLNodeSource methods ***/
static HRESULT WINAPI xmlparser_SetFactory(IXMLParser *iface, IXMLNodeFactory *pNodeFactory)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    if(This->nodefactory)
        IXMLNodeFactory_Release(This->nodefactory);

    This->nodefactory = pNodeFactory;
    if(This->nodefactory)
        IXMLNodeFactory_AddRef(This->nodefactory);

    return S_OK;
}

static HRESULT WINAPI xmlparser_GetFactory(IXMLParser *iface, IXMLNodeFactory **ppNodeFactory)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    if(!ppNodeFactory)
        return E_INVALIDARG;

    *ppNodeFactory = This->nodefactory;

    if(*ppNodeFactory)
        IXMLNodeFactory_AddRef(*ppNodeFactory);

    return S_OK;
}

static HRESULT WINAPI xmlparser_Abort(IXMLParser *iface, BSTR bstrErrorInfo)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p, %s)\n", This, debugstr_w(bstrErrorInfo));

    return E_NOTIMPL;
}

static ULONG WINAPI xmlparser_GetLineNumber(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return 0;
}

static ULONG WINAPI xmlparser_GetLinePosition(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return 0;
}

static ULONG WINAPI xmlparser_GetAbsolutePosition(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return 0;
}

static HRESULT WINAPI xmlparser_GetLineBuffer(IXMLParser *iface, const WCHAR **ppBuf,
                ULONG *len, ULONG *startPos)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %p %p %p)\n", This, ppBuf, len, startPos);

    return 0;
}

static HRESULT WINAPI xmlparser_GetLastError(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_GetErrorInfo(IXMLParser *iface, BSTR *pErrorInfo)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %p)\n", This, pErrorInfo);

    return E_NOTIMPL;
}

static ULONG WINAPI xmlparser_GetFlags(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return This->flags;
}

static HRESULT WINAPI xmlparser_GetURL(IXMLParser *iface, const WCHAR **ppBuf)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %p)\n", This, ppBuf);

    return E_NOTIMPL;
}

/*** IXMLParser methods ***/
static HRESULT WINAPI xmlparser_SetURL(IXMLParser *iface,const WCHAR *pszBaseUrl,
                const WCHAR *relativeUrl, BOOL async)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s %s %d)\n", This, debugstr_w(pszBaseUrl), debugstr_w(relativeUrl), async);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_Load(IXMLParser *iface, BOOL bFullyAvailable,
                IMoniker *pMon, LPBC pBC, DWORD dwMode)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %d %p %p %d)\n", This, bFullyAvailable, pMon, pBC, dwMode);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_SetInput(IXMLParser *iface, IUnknown *pStm)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    if(!pStm)
        return E_INVALIDARG;

    if(This->input)
        IUnknown_Release(This->input);

    This->input = pStm;
    IUnknown_AddRef(This->input);

    return S_OK;
}

static HRESULT WINAPI xmlparser_PushData(IXMLParser *iface, const char *pData,
                ULONG nChars, BOOL fLastBuffer)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s %d %d)\n", This, debugstr_a(pData), nChars, fLastBuffer);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_LoadDTD(IXMLParser *iface, const WCHAR *baseUrl,
                const WCHAR *relativeUrl)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s %s)\n", This, debugstr_w(baseUrl), debugstr_w(relativeUrl));

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_LoadEntity(IXMLParser *iface, const WCHAR *baseUrl,
                const WCHAR *relativeUrl, BOOL fpe)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s %s %d)\n", This, debugstr_w(baseUrl), debugstr_w(relativeUrl), fpe);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_ParseEntity(IXMLParser *iface, const WCHAR *text,
                ULONG len, BOOL fpe)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s %d %d)\n", This, debugstr_w(text), len, fpe);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_ExpandEntity(IXMLParser *iface, const WCHAR *text,
                ULONG len)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s %d)\n", This, debugstr_w(text), len);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_SetRoot(IXMLParser *iface, PVOID pRoot)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %p)\n", This, pRoot);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_GetRoot( IXMLParser *iface, PVOID *ppRoot)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %p)\n", This, ppRoot);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_Run(IXMLParser *iface, LONG chars)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %d)\n", This, chars);

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_GetParserState(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_Suspend(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_Reset(IXMLParser *iface)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_SetFlags(IXMLParser *iface, ULONG flags)
{
    xmlparser *This = impl_from_IXMLParser( iface );

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

    This->flags = flags;

    return S_OK;
}

static HRESULT WINAPI xmlparser_SetSecureBaseURL(IXMLParser *iface, const WCHAR *baseUrl)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %s)\n", This, debugstr_w(baseUrl));

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlparser_GetSecureBaseURL( IXMLParser *iface, const WCHAR **ppBuf)
{
    xmlparser *This = impl_from_IXMLParser( iface );

    FIXME("(%p %p)\n", This, ppBuf);

    return E_NOTIMPL;
}


static const struct IXMLParserVtbl xmlparser_vtbl =
{
    xmlparser_QueryInterface,
    xmlparser_AddRef,
    xmlparser_Release,
    xmlparser_SetFactory,
    xmlparser_GetFactory,
    xmlparser_Abort,
    xmlparser_GetLineNumber,
    xmlparser_GetLinePosition,
    xmlparser_GetAbsolutePosition,
    xmlparser_GetLineBuffer,
    xmlparser_GetLastError,
    xmlparser_GetErrorInfo,
    xmlparser_GetFlags,
    xmlparser_GetURL,
    xmlparser_SetURL,
    xmlparser_Load,
    xmlparser_SetInput,
    xmlparser_PushData,
    xmlparser_LoadDTD,
    xmlparser_LoadEntity,
    xmlparser_ParseEntity,
    xmlparser_ExpandEntity,
    xmlparser_SetRoot,
    xmlparser_GetRoot,
    xmlparser_Run,
    xmlparser_GetParserState,
    xmlparser_Suspend,
    xmlparser_Reset,
    xmlparser_SetFlags,
    xmlparser_SetSecureBaseURL,
    xmlparser_GetSecureBaseURL
};

HRESULT XMLParser_create(void **ppObj)
{
    xmlparser *This;

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

    This = heap_alloc( sizeof(xmlparser) );
    if(!This)
        return E_OUTOFMEMORY;

    This->IXMLParser_iface.lpVtbl = &xmlparser_vtbl;
    This->nodefactory = NULL;
    This->input = NULL;
    This->flags = 0;
    This->ref = 1;

    *ppObj = &This->IXMLParser_iface;

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

    return S_OK;
}
