/*
 *    IMXNamespaceManager implementation
 *
 * Copyright 2011-2012 Nikolay Sivov 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
 */

#define COBJMACROS

#include "config.h"

#include <stdarg.h>
#ifdef HAVE_LIBXML2
# include <libxml/parser.h>
# include <libxml/xmlerror.h>
# include <libxml/encoding.h>
#endif

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

#include "msxml_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

struct ns
{
    BSTR prefix;
    BSTR uri;
};

struct nscontext
{
    struct list entry;

    struct ns *ns;
    int   count;
    int   max_alloc;
};

#define DEFAULT_PREFIX_ALLOC_COUNT 16

static const WCHAR xmlW[] = {'x','m','l',0};
static const WCHAR xmluriW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g',
    '/','X','M','L','/','1','9','9','8','/','n','a','m','e','s','p','a','c','e',0};

typedef struct
{
    DispatchEx dispex;
    IMXNamespaceManager   IMXNamespaceManager_iface;
    IVBMXNamespaceManager IVBMXNamespaceManager_iface;
    LONG ref;

    struct list ctxts;

    VARIANT_BOOL override;
} namespacemanager;

static inline namespacemanager *impl_from_IMXNamespaceManager( IMXNamespaceManager *iface )
{
    return CONTAINING_RECORD(iface, namespacemanager, IMXNamespaceManager_iface);
}

static inline namespacemanager *impl_from_IVBMXNamespaceManager( IVBMXNamespaceManager *iface )
{
    return CONTAINING_RECORD(iface, namespacemanager, IVBMXNamespaceManager_iface);
}

static HRESULT declare_prefix(namespacemanager *This, const WCHAR *prefix, const WCHAR *uri)
{
    struct nscontext *ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
    static const WCHAR emptyW[] = {0};
    struct ns *ns;
    int i;

    if (ctxt->count == ctxt->max_alloc)
    {
        ctxt->max_alloc *= 2;
        ctxt->ns = heap_realloc(ctxt->ns, ctxt->max_alloc*sizeof(*ctxt->ns));
    }

    if (!prefix) prefix = emptyW;

    ns = NULL;
    for (i = 0; i < ctxt->count; i++)
        if (!strcmpW(ctxt->ns[i].prefix, prefix))
        {
            ns = &ctxt->ns[i];
            break;
        }

    if (ns)
    {
        if (This->override == VARIANT_TRUE)
        {
            SysFreeString(ns->uri);
            ns->uri = SysAllocString(uri);
            return S_FALSE;
        }
        else
            return E_FAIL;
    }
    else
    {
        ctxt->ns[ctxt->count].prefix = SysAllocString(prefix);
        ctxt->ns[ctxt->count].uri = SysAllocString(uri);
        ctxt->count++;
    }

    return S_OK;
}

/* returned stored pointer, caller needs to copy it */
static HRESULT get_declared_prefix_idx(const struct nscontext *ctxt, LONG index, BSTR *prefix)
{
    *prefix = NULL;

    if (index >= ctxt->count || index < 0) return E_FAIL;

    if (index > 0) index = ctxt->count - index;
    *prefix = ctxt->ns[index].prefix;

    return S_OK;
}

/* returned stored pointer, caller needs to copy it */
static HRESULT get_declared_prefix_uri(const struct list *ctxts, const WCHAR *uri, BSTR *prefix)
{
    struct nscontext *ctxt;

    LIST_FOR_EACH_ENTRY(ctxt, ctxts, struct nscontext, entry)
    {
        int i;
        for (i = 0; i < ctxt->count; i++)
            if (!strcmpW(ctxt->ns[i].uri, uri))
            {
                *prefix = ctxt->ns[i].prefix;
                return S_OK;
            }
    }

    *prefix = NULL;
    return E_FAIL;
}

static HRESULT get_uri_from_prefix(const struct nscontext *ctxt, const WCHAR *prefix, BSTR *uri)
{
    int i;

    for (i = 0; i < ctxt->count; i++)
        if (!strcmpW(ctxt->ns[i].prefix, prefix))
        {
            *uri = ctxt->ns[i].uri;
            return S_OK;
        }

    *uri = NULL;
    return S_FALSE;
}

static struct nscontext* alloc_ns_context(void)
{
    struct nscontext *ctxt;

    ctxt = heap_alloc(sizeof(*ctxt));
    if (!ctxt) return NULL;

    ctxt->count = 0;
    ctxt->max_alloc = DEFAULT_PREFIX_ALLOC_COUNT;
    ctxt->ns = heap_alloc(ctxt->max_alloc*sizeof(*ctxt->ns));
    if (!ctxt->ns)
    {
        heap_free(ctxt);
        return NULL;
    }

    /* first allocated prefix is always 'xml' */
    ctxt->ns[0].prefix = SysAllocString(xmlW);
    ctxt->ns[0].uri = SysAllocString(xmluriW);
    ctxt->count++;
    if (!ctxt->ns[0].prefix || !ctxt->ns[0].uri)
    {
        heap_free(ctxt->ns);
        heap_free(ctxt);
        return NULL;
    }

    return ctxt;
}

static void free_ns_context(struct nscontext *ctxt)
{
    int i;

    for (i = 0; i < ctxt->count; i++)
    {
        SysFreeString(ctxt->ns[i].prefix);
        SysFreeString(ctxt->ns[i].uri);
    }

    heap_free(ctxt->ns);
    heap_free(ctxt);
}

static HRESULT WINAPI namespacemanager_QueryInterface(IMXNamespaceManager *iface, REFIID riid, void **ppvObject)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_QueryInterface(&This->IVBMXNamespaceManager_iface, riid, ppvObject);
}

static ULONG WINAPI namespacemanager_AddRef(IMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_AddRef(&This->IVBMXNamespaceManager_iface);
}

static ULONG WINAPI namespacemanager_Release(IMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_Release(&This->IVBMXNamespaceManager_iface);
}

static HRESULT WINAPI namespacemanager_putAllowOverride(IMXNamespaceManager *iface,
    VARIANT_BOOL override)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_put_allowOverride(&This->IVBMXNamespaceManager_iface, override);
}

static HRESULT WINAPI namespacemanager_getAllowOverride(IMXNamespaceManager *iface,
    VARIANT_BOOL *override)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_get_allowOverride(&This->IVBMXNamespaceManager_iface, override);
}

static HRESULT WINAPI namespacemanager_reset(IMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_reset(&This->IVBMXNamespaceManager_iface);
}

static HRESULT WINAPI namespacemanager_pushContext(IMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_pushContext(&This->IVBMXNamespaceManager_iface);
}

static HRESULT WINAPI namespacemanager_pushNodeContext(IMXNamespaceManager *iface,
    IXMLDOMNode *node, VARIANT_BOOL deep)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_pushNodeContext(&This->IVBMXNamespaceManager_iface, node, deep);
}

static HRESULT WINAPI namespacemanager_popContext(IMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    return IVBMXNamespaceManager_popContext(&This->IVBMXNamespaceManager_iface);
}

static HRESULT WINAPI namespacemanager_declarePrefix(IMXNamespaceManager *iface,
    const WCHAR *prefix, const WCHAR *namespaceURI)
{
    static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};

    namespacemanager *This = impl_from_IMXNamespaceManager( iface );

    TRACE("(%p)->(%s %s)\n", This, debugstr_w(prefix), debugstr_w(namespaceURI));

    if (prefix && (!strcmpW(prefix, xmlW) || !strcmpW(prefix, xmlnsW) || !namespaceURI))
        return E_INVALIDARG;

    return declare_prefix(This, prefix, namespaceURI);
}

static HRESULT WINAPI namespacemanager_getDeclaredPrefix(IMXNamespaceManager *iface,
    LONG index, WCHAR *prefix, int *prefix_len)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    struct nscontext *ctxt;
    HRESULT hr;
    BSTR prfx;

    TRACE("(%p)->(%d %p %p)\n", This, index, prefix, prefix_len);

    if (!prefix_len) return E_POINTER;

    ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
    hr = get_declared_prefix_idx(ctxt, index, &prfx);
    if (hr != S_OK) return hr;

    if (prefix)
    {
        if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL;
        strcpyW(prefix, prfx);
    }

    *prefix_len = SysStringLen(prfx);

    return S_OK;
}

static HRESULT WINAPI namespacemanager_getPrefix(IMXNamespaceManager *iface,
    const WCHAR *uri, LONG index, WCHAR *prefix, int *prefix_len)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    HRESULT hr;
    BSTR prfx;

    TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(uri), index, prefix, prefix_len);

    if (!uri || !*uri || !prefix_len) return E_INVALIDARG;

    hr = get_declared_prefix_uri(&This->ctxts, uri, &prfx);
    if (hr == S_OK)
    {
        /* TODO: figure out what index argument is for */
        if (index) return E_FAIL;

        if (prefix)
        {
            if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL;
            strcpyW(prefix, prfx);
        }

        *prefix_len = SysStringLen(prfx);
        TRACE("prefix=%s\n", debugstr_w(prfx));
    }

    return hr;
}

static HRESULT WINAPI namespacemanager_getURI(IMXNamespaceManager *iface,
    const WCHAR *prefix, IXMLDOMNode *node, WCHAR *uri, int *uri_len)
{
    namespacemanager *This = impl_from_IMXNamespaceManager( iface );
    struct nscontext *ctxt;
    HRESULT hr;
    BSTR urib;

    TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_w(prefix), node, uri, uri_len);

    if (!prefix) return E_INVALIDARG;
    if (!uri_len) return E_POINTER;

    if (node)
    {
        FIXME("namespaces from DOM node not supported\n");
        return E_NOTIMPL;
    }

    ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
    hr = get_uri_from_prefix(ctxt, prefix, &urib);
    if (hr == S_OK)
    {
        if (uri)
        {
           if (*uri_len < (INT)SysStringLen(urib)) return E_XML_BUFFERTOOSMALL;
           strcpyW(uri, urib);
        }
    }
    else
        if (uri) *uri = 0;

    *uri_len = SysStringLen(urib);

    return hr;
}

static const struct IMXNamespaceManagerVtbl MXNamespaceManagerVtbl =
{
    namespacemanager_QueryInterface,
    namespacemanager_AddRef,
    namespacemanager_Release,
    namespacemanager_putAllowOverride,
    namespacemanager_getAllowOverride,
    namespacemanager_reset,
    namespacemanager_pushContext,
    namespacemanager_pushNodeContext,
    namespacemanager_popContext,
    namespacemanager_declarePrefix,
    namespacemanager_getDeclaredPrefix,
    namespacemanager_getPrefix,
    namespacemanager_getURI
};

static HRESULT WINAPI vbnamespacemanager_QueryInterface(IVBMXNamespaceManager *iface, REFIID riid, void **obj)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    if ( IsEqualGUID( riid, &IID_IMXNamespaceManager) ||
         IsEqualGUID( riid, &IID_IUnknown) )
    {
        *obj = &This->IMXNamespaceManager_iface;
    }
    else if ( IsEqualGUID( riid, &IID_IVBMXNamespaceManager) ||
              IsEqualGUID( riid, &IID_IDispatch) )
    {
        *obj = &This->IVBMXNamespaceManager_iface;
    }
    else if (dispex_query_interface(&This->dispex, riid, obj))
    {
        return *obj ? S_OK : E_NOINTERFACE;
    }
    else
    {
        TRACE("Unsupported interface %s\n", debugstr_guid(riid));
        *obj = NULL;
        return E_NOINTERFACE;
    }

    IVBMXNamespaceManager_AddRef( iface );

    return S_OK;
}

static ULONG WINAPI vbnamespacemanager_AddRef(IVBMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    ULONG ref = InterlockedIncrement( &This->ref );
    TRACE("(%p)->(%u)\n", This, ref );
    return ref;
}

static ULONG WINAPI vbnamespacemanager_Release(IVBMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    ULONG ref = InterlockedDecrement( &This->ref );

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

    if ( ref == 0 )
    {
        struct nscontext *ctxt, *ctxt2;

        LIST_FOR_EACH_ENTRY_SAFE(ctxt, ctxt2, &This->ctxts, struct nscontext, entry)
        {
            list_remove(&ctxt->entry);
            free_ns_context(ctxt);
        }

        heap_free( This );
    }

    return ref;
}

static HRESULT WINAPI vbnamespacemanager_GetTypeInfoCount(IVBMXNamespaceManager *iface, UINT *pctinfo)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
}

static HRESULT WINAPI vbnamespacemanager_GetTypeInfo(IVBMXNamespaceManager *iface, UINT iTInfo,
        LCID lcid, ITypeInfo **ppTInfo)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
        iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI vbnamespacemanager_GetIDsOfNames(IVBMXNamespaceManager *iface, REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
        riid, rgszNames, cNames, lcid, rgDispId);
}

static HRESULT WINAPI vbnamespacemanager_Invoke(IVBMXNamespaceManager *iface, DISPID dispIdMember, REFIID riid,
        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
        EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
        dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI vbnamespacemanager_put_allowOverride(IVBMXNamespaceManager *iface,
    VARIANT_BOOL override)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );

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

    return S_OK;
}

static HRESULT WINAPI vbnamespacemanager_get_allowOverride(IVBMXNamespaceManager *iface,
    VARIANT_BOOL *override)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );

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

    if (!override) return E_POINTER;
    *override = This->override;

    return S_OK;
}

static HRESULT WINAPI vbnamespacemanager_reset(IVBMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI vbnamespacemanager_pushContext(IVBMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    struct nscontext *ctxt;

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

    ctxt = alloc_ns_context();
    if (!ctxt) return E_OUTOFMEMORY;

    list_add_head(&This->ctxts, &ctxt->entry);

    return S_OK;
}

static HRESULT WINAPI vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager *iface,
    IXMLDOMNode *node, VARIANT_BOOL deep)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    FIXME("(%p)->(%p %d): stub\n", This, node, deep);
    return E_NOTIMPL;
}

static HRESULT WINAPI vbnamespacemanager_popContext(IVBMXNamespaceManager *iface)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    const struct list *next;
    struct nscontext *ctxt;

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

    next = list_next(&This->ctxts, list_head(&This->ctxts));
    if (!next) return E_FAIL;

    ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
    list_remove(list_head(&This->ctxts));

    free_ns_context(ctxt);

    return S_OK;
}

static HRESULT WINAPI vbnamespacemanager_declarePrefix(IVBMXNamespaceManager *iface,
    BSTR prefix, BSTR namespaceURI)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    return IMXNamespaceManager_declarePrefix(&This->IMXNamespaceManager_iface, prefix, namespaceURI);
}

static HRESULT WINAPI vbnamespacemanager_getDeclaredPrefixes(IVBMXNamespaceManager *iface,
    IMXNamespacePrefixes** prefixes)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    FIXME("(%p)->(%p): stub\n", This, prefixes);
    return E_NOTIMPL;
}

static HRESULT WINAPI vbnamespacemanager_getPrefixes(IVBMXNamespaceManager *iface,
    BSTR namespaceURI, IMXNamespacePrefixes** prefixes)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(namespaceURI), prefixes);
    return E_NOTIMPL;
}

static HRESULT WINAPI vbnamespacemanager_getURI(IVBMXNamespaceManager *iface,
    BSTR prefix, VARIANT* uri)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(prefix), uri);
    return E_NOTIMPL;
}

static HRESULT WINAPI vbnamespacemanager_getURIFromNode(IVBMXNamespaceManager *iface,
    BSTR prefix, IXMLDOMNode *node, VARIANT *uri)
{
    namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
    FIXME("(%p)->(%s %p %p): stub\n", This, debugstr_w(prefix), node, uri);
    return E_NOTIMPL;
}

static const struct IVBMXNamespaceManagerVtbl VBMXNamespaceManagerVtbl =
{
    vbnamespacemanager_QueryInterface,
    vbnamespacemanager_AddRef,
    vbnamespacemanager_Release,
    vbnamespacemanager_GetTypeInfoCount,
    vbnamespacemanager_GetTypeInfo,
    vbnamespacemanager_GetIDsOfNames,
    vbnamespacemanager_Invoke,
    vbnamespacemanager_put_allowOverride,
    vbnamespacemanager_get_allowOverride,
    vbnamespacemanager_reset,
    vbnamespacemanager_pushContext,
    vbnamespacemanager_pushNodeContext,
    vbnamespacemanager_popContext,
    vbnamespacemanager_declarePrefix,
    vbnamespacemanager_getDeclaredPrefixes,
    vbnamespacemanager_getPrefixes,
    vbnamespacemanager_getURI,
    vbnamespacemanager_getURIFromNode
};

static const tid_t namespacemanager_iface_tids[] = {
    IVBMXNamespaceManager_tid,
    0
};

static dispex_static_data_t namespacemanager_dispex = {
    NULL,
    IVBMXNamespaceManager_tid,
    NULL,
    namespacemanager_iface_tids
};

HRESULT MXNamespaceManager_create(void **obj)
{
    namespacemanager *This;
    struct nscontext *ctxt;

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

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

    This->IMXNamespaceManager_iface.lpVtbl = &MXNamespaceManagerVtbl;
    This->IVBMXNamespaceManager_iface.lpVtbl = &VBMXNamespaceManagerVtbl;
    This->ref = 1;
    init_dispex(&This->dispex, (IUnknown*)&This->IVBMXNamespaceManager_iface, &namespacemanager_dispex);

    list_init(&This->ctxts);
    ctxt = alloc_ns_context();
    if (!ctxt)
    {
        heap_free(This);
        return E_OUTOFMEMORY;
    }

    list_add_head(&This->ctxts, &ctxt->entry);

    This->override = VARIANT_TRUE;

    *obj = &This->IMXNamespaceManager_iface;

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

    return S_OK;
}
