/*
 * Web Services on Devices
 *
 * Copyright 2017 Owen Rudge 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 <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "wsdapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);

#define WSD_MAX_TEXT_LENGTH 8192

static LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value)
{
    int valueLen;
    LPWSTR dup;

    valueLen = lstrlenW(value) + 1;

    dup = WSDAllocateLinkedMemory(parentMemoryBlock, valueLen * sizeof(WCHAR));

    if (dup) memcpy(dup, value, valueLen * sizeof(WCHAR));
    return dup;
}

static WSDXML_NAMESPACE *duplicate_namespace(void *parentMemoryBlock, WSDXML_NAMESPACE *ns)
{
    WSDXML_NAMESPACE *newNs;

    newNs = WSDAllocateLinkedMemory(parentMemoryBlock, sizeof(WSDXML_NAMESPACE));

    if (newNs == NULL)
    {
        return NULL;
    }

    newNs->Encoding = ns->Encoding;

    /* On Windows, both Names and NamesCount are set to null even if there are names present */
    newNs->NamesCount = 0;
    newNs->Names = NULL;

    newNs->PreferredPrefix = duplicate_string(newNs, ns->PreferredPrefix);
    newNs->Uri = duplicate_string(newNs, ns->Uri);

    return newNs;
}

static WSDXML_NAME *duplicate_name(void *parentMemoryBlock, WSDXML_NAME *name)
{
    WSDXML_NAME *dup;

    dup = WSDAllocateLinkedMemory(parentMemoryBlock, sizeof(WSDXML_NAME));

    if (dup == NULL)
    {
        return NULL;
    }

    dup->Space = duplicate_namespace(dup, name->Space);
    dup->LocalName = duplicate_string(dup, name->LocalName);

    if (dup->LocalName == NULL)
    {
        WSDFreeLinkedMemory(dup);
        return NULL;
    }

    return dup;
}

HRESULT WINAPI WSDXMLAddChild(WSDXML_ELEMENT *pParent, WSDXML_ELEMENT *pChild)
{
    WSDXML_NODE *currentNode;

    TRACE("(%p, %p)\n", pParent, pChild);

    if ((pParent == NULL) || (pChild == NULL) || (pChild->Node.Parent != NULL))
    {
        return E_INVALIDARG;
    }

    /* See if the parent already has a child */
    currentNode = pParent->FirstChild;

    if (currentNode == NULL)
    {
        pParent->FirstChild = (WSDXML_NODE *)pChild;
    }
    else
    {
        /* Find the last sibling node and make this child the next sibling */
        WSDXMLAddSibling((WSDXML_ELEMENT *)currentNode, pChild);
    }

    pChild->Node.Parent = pParent;

    /* Link the memory allocations */
    WSDAttachLinkedMemory(pParent, pChild);

    return S_OK;
}

HRESULT WINAPI WSDXMLAddSibling(WSDXML_ELEMENT *pFirst, WSDXML_ELEMENT *pSecond)
{
    WSDXML_NODE *currentNode;

    TRACE("(%p, %p)\n", pFirst, pSecond);

    if ((pFirst == NULL) || (pSecond == NULL))
    {
        return E_INVALIDARG;
    }

    /* See if the first node already has a sibling */
    currentNode = pFirst->Node.Next;

    if (currentNode == NULL)
    {
        pFirst->Node.Next = (WSDXML_NODE *)pSecond;
    }
    else
    {
        /* Find the last sibling node and make the second element the next sibling */
        while (1)
        {
            if (currentNode->Next == NULL)
            {
                currentNode->Next = (WSDXML_NODE *)pSecond;
                break;
            }

            currentNode = currentNode->Next;
        }
    }

    /* Reparent the second node under the first */
    pSecond->Node.Parent = pFirst->Node.Parent;

    /* Link the memory allocations */
    WSDAttachLinkedMemory(pFirst->Node.Parent, pSecond);

    return S_OK;
}

HRESULT WINAPI WSDXMLBuildAnyForSingleElement(WSDXML_NAME *pElementName, LPCWSTR pszText, WSDXML_ELEMENT **ppAny)
{
    WSDXML_TEXT *child;

    TRACE("(%p, %s, %p)\n", pElementName, debugstr_w(pszText), ppAny);

    if ((pElementName == NULL) || ((pszText != NULL) && (lstrlenW(pszText) > WSD_MAX_TEXT_LENGTH)))
    {
        return E_INVALIDARG;
    }

    if (ppAny == NULL)
    {
        return E_POINTER;
    }

    *ppAny = WSDAllocateLinkedMemory(NULL, sizeof(WSDXML_ELEMENT));

    if (*ppAny == NULL)
    {
        return E_OUTOFMEMORY;
    }

    ZeroMemory(*ppAny, sizeof(WSDXML_ELEMENT));

    (*ppAny)->Name = duplicate_name(*ppAny, pElementName);

    if ((*ppAny)->Name == NULL)
    {
        WSDFreeLinkedMemory(*ppAny);
        return E_OUTOFMEMORY;
    }

    if (pszText != NULL)
    {
        child = WSDAllocateLinkedMemory(*ppAny, sizeof(WSDXML_TEXT));

        if (child == NULL)
        {
            WSDFreeLinkedMemory(*ppAny);
            return E_OUTOFMEMORY;
        }

        child->Node.Parent = *ppAny;
        child->Node.Next = NULL;
        child->Node.Type = TextType;
        child->Text = duplicate_string(child, pszText);

        if (child->Text == NULL)
        {
            WSDFreeLinkedMemory(*ppAny);
            return E_OUTOFMEMORY;
        }

        (*ppAny)->FirstChild = (WSDXML_NODE *)child;
    }

    return S_OK;
}

HRESULT WINAPI WSDXMLCleanupElement(WSDXML_ELEMENT *pAny)
{
    TRACE("(%p)\n", pAny);

    if (pAny == NULL)
    {
        return E_INVALIDARG;
    }

    WSDFreeLinkedMemory(pAny);
    return S_OK;
}

HRESULT WINAPI WSDXMLGetValueFromAny(const WCHAR *pszNamespace, const WCHAR *pszName, WSDXML_ELEMENT *pAny, LPCWSTR *ppszValue)
{
    WSDXML_ELEMENT *element;
    WSDXML_TEXT *text;

    if (pAny == NULL)
        return E_INVALIDARG;

    if (ppszValue == NULL)
        return E_POINTER;

    if ((pszNamespace == NULL) || (pszName == NULL) || (lstrlenW(pszNamespace) > WSD_MAX_TEXT_LENGTH) || (lstrlenW(pszName) > WSD_MAX_TEXT_LENGTH))
        return E_INVALIDARG;

    element = pAny;

    while (element != NULL)
    {
        if (element->Node.Type == ElementType)
        {
            if ((lstrcmpW(element->Name->LocalName, pszName) == 0) && (lstrcmpW(element->Name->Space->Uri, pszNamespace) == 0))
            {
                if ((element->FirstChild == NULL) || (element->FirstChild->Type != TextType))
                {
                    return E_FAIL;
                }

                text = (WSDXML_TEXT *) element->FirstChild;
                *ppszValue = (LPCWSTR) text->Text;

                return S_OK;
            }
        }

        element = (WSDXML_ELEMENT *) element->Node.Next;
    }

    return E_FAIL;
}

/* IWSDXMLContext implementation */

struct xmlNamespace
{
    struct list entry;
    WSDXML_NAMESPACE *namespace;
};

typedef struct IWSDXMLContextImpl
{
    IWSDXMLContext IWSDXMLContext_iface;
    LONG ref;

    struct list *namespaces;
    int nextUnknownPrefix;
} IWSDXMLContextImpl;

static WSDXML_NAMESPACE *find_namespace(struct list *namespaces, LPCWSTR uri)
{
    struct xmlNamespace *ns;

    LIST_FOR_EACH_ENTRY(ns, namespaces, struct xmlNamespace, entry)
    {
        if (lstrcmpW(ns->namespace->Uri, uri) == 0)
        {
            return ns->namespace;
        }
    }

    return NULL;
}

static WSDXML_NAME *find_name(WSDXML_NAMESPACE *ns, LPCWSTR name)
{
    int i;

    for (i = 0; i < ns->NamesCount; i++)
    {
        if (lstrcmpW(ns->Names[i].LocalName, name) == 0)
        {
            return &ns->Names[i];
        }
    }

    return NULL;
}

static WSDXML_NAME *add_name(WSDXML_NAMESPACE *ns, LPCWSTR name)
{
    WSDXML_NAME *names;
    WSDXML_NAME *newName;
    int i;

    names = WSDAllocateLinkedMemory(ns, sizeof(WSDXML_NAME) * (ns->NamesCount + 1));

    if (names == NULL)
    {
        return NULL;
    }

    if (ns->NamesCount > 0)
    {
        /* Copy the existing names array over to the new allocation */
        memcpy(names, ns->Names, sizeof(WSDXML_NAME) * ns->NamesCount);

        for (i = 0; i < ns->NamesCount; i++)
        {
            /* Attach the local name memory to the new names allocation */
            WSDAttachLinkedMemory(names, names[i].LocalName);
        }

        WSDFreeLinkedMemory(ns->Names);
    }

    ns->Names = names;

    newName = &names[ns->NamesCount];

    newName->LocalName = duplicate_string(names, name);
    newName->Space = ns;

    if (newName->LocalName == NULL)
    {
        return NULL;
    }

    ns->NamesCount++;
    return newName;
}

static BOOL is_prefix_unique(struct list *namespaces, LPCWSTR prefix)
{
    struct xmlNamespace *ns;

    LIST_FOR_EACH_ENTRY(ns, namespaces, struct xmlNamespace, entry)
    {
        if (lstrcmpW(ns->namespace->PreferredPrefix, prefix) == 0)
        {
            return FALSE;
        }
    }

    return TRUE;
}

static LPWSTR generate_namespace_prefix(IWSDXMLContextImpl *impl, void *parentMemoryBlock, LPCWSTR uri)
{
    WCHAR formatString[] = { 'u','n','%','d', 0 };
    WCHAR suggestedPrefix[7];

    /* Find a unique prefix */
    while (impl->nextUnknownPrefix < 1000)
    {
        wsprintfW(suggestedPrefix, formatString, impl->nextUnknownPrefix++);

        /* For the unlikely event where somebody has explicitly created a prefix called 'unX', check it is unique */
        if (is_prefix_unique(impl->namespaces, suggestedPrefix))
        {
            return duplicate_string(parentMemoryBlock, suggestedPrefix);
        }
    }

    return NULL;
}

static WSDXML_NAMESPACE *add_namespace(struct list *namespaces, LPCWSTR uri)
{
    struct xmlNamespace *ns = WSDAllocateLinkedMemory(namespaces, sizeof(struct xmlNamespace));

    if (ns == NULL)
    {
        return NULL;
    }

    ns->namespace = WSDAllocateLinkedMemory(ns, sizeof(WSDXML_NAMESPACE));

    if (ns->namespace == NULL)
    {
        WSDFreeLinkedMemory(ns);
        return NULL;
    }

    ZeroMemory(ns->namespace, sizeof(WSDXML_NAMESPACE));
    ns->namespace->Uri = duplicate_string(ns->namespace, uri);

    if (ns->namespace->Uri == NULL)
    {
        WSDFreeLinkedMemory(ns);
        return NULL;
    }

    list_add_tail(namespaces, &ns->entry);
    return ns->namespace;
}

static inline IWSDXMLContextImpl *impl_from_IWSDXMLContext(IWSDXMLContext *iface)
{
    return CONTAINING_RECORD(iface, IWSDXMLContextImpl, IWSDXMLContext_iface);
}

static HRESULT WINAPI IWSDXMLContextImpl_QueryInterface(IWSDXMLContext *iface, REFIID riid, void **ppv)
{
    IWSDXMLContextImpl *This = impl_from_IWSDXMLContext(iface);

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

    if (!ppv)
    {
        WARN("Invalid parameter\n");
        return E_INVALIDARG;
    }

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IWSDXMLContext))
    {
        *ppv = &This->IWSDXMLContext_iface;
    }
    else
    {
        WARN("Unknown IID %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI IWSDXMLContextImpl_AddRef(IWSDXMLContext *iface)
{
    IWSDXMLContextImpl *This = impl_from_IWSDXMLContext(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

static ULONG WINAPI IWSDXMLContextImpl_Release(IWSDXMLContext *iface)
{
    IWSDXMLContextImpl *This = impl_from_IWSDXMLContext(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        WSDFreeLinkedMemory(This);
    }

    return ref;
}

static HRESULT WINAPI IWSDXMLContextImpl_AddNamespace(IWSDXMLContext *iface, LPCWSTR pszUri, LPCWSTR pszSuggestedPrefix, WSDXML_NAMESPACE **ppNamespace)
{
    IWSDXMLContextImpl *This = impl_from_IWSDXMLContext(iface);
    WSDXML_NAMESPACE *ns;
    LPCWSTR newPrefix = NULL;
    BOOL setNewPrefix;

    TRACE("(%p, %s, %s, %p)\n", This, debugstr_w(pszUri), debugstr_w(pszSuggestedPrefix), ppNamespace);

    if ((pszUri == NULL) || (pszSuggestedPrefix == NULL) || (lstrlenW(pszUri) > WSD_MAX_TEXT_LENGTH) ||
        (lstrlenW(pszSuggestedPrefix) > WSD_MAX_TEXT_LENGTH))
    {
        return E_INVALIDARG;
    }

    ns = find_namespace(This->namespaces, pszUri);

    if (ns == NULL)
    {
        ns = add_namespace(This->namespaces, pszUri);

        if (ns == NULL)
        {
            return E_OUTOFMEMORY;
        }
    }

    setNewPrefix = (ns->PreferredPrefix == NULL);

    if ((ns->PreferredPrefix == NULL) || (lstrcmpW(ns->PreferredPrefix, pszSuggestedPrefix) != 0))
    {
        newPrefix = pszSuggestedPrefix;
        setNewPrefix = TRUE;
    }

    if (setNewPrefix)
    {
        WSDFreeLinkedMemory((void *)ns->PreferredPrefix);
        ns->PreferredPrefix = NULL;

        if ((newPrefix != NULL) && (is_prefix_unique(This->namespaces, newPrefix)))
        {
            ns->PreferredPrefix = duplicate_string(ns, newPrefix);
        }
        else
        {
            ns->PreferredPrefix = generate_namespace_prefix(This, ns, pszUri);
            if (ns->PreferredPrefix == NULL)
            {
                return E_FAIL;
            }
        }
    }

    if (ppNamespace != NULL)
    {
        *ppNamespace = duplicate_namespace(NULL, ns);

        if (*ppNamespace == NULL)
        {
            return E_OUTOFMEMORY;
        }
    }

    return S_OK;
}

static HRESULT WINAPI IWSDXMLContextImpl_AddNameToNamespace(IWSDXMLContext *iface, LPCWSTR pszUri, LPCWSTR pszName, WSDXML_NAME **ppName)
{
    IWSDXMLContextImpl *This = impl_from_IWSDXMLContext(iface);
    WSDXML_NAMESPACE *ns;
    WSDXML_NAME *name;

    TRACE("(%p, %s, %s, %p)\n", This, debugstr_w(pszUri), debugstr_w(pszName), ppName);

    if ((pszUri == NULL) || (pszName == NULL) || (lstrlenW(pszUri) > WSD_MAX_TEXT_LENGTH) || (lstrlenW(pszName) > WSD_MAX_TEXT_LENGTH))
    {
        return E_INVALIDARG;
    }

    ns = find_namespace(This->namespaces, pszUri);

    if (ns == NULL)
    {
        /* The namespace doesn't exist, add it */
        ns = add_namespace(This->namespaces, pszUri);

        if (ns == NULL)
        {
            return E_OUTOFMEMORY;
        }

        ns->PreferredPrefix = generate_namespace_prefix(This, ns, pszUri);
        if (ns->PreferredPrefix == NULL)
        {
            return E_FAIL;
        }
    }

    name = find_name(ns, pszName);

    if (name == NULL)
    {
        name = add_name(ns, pszName);

        if (name == NULL)
        {
            return E_OUTOFMEMORY;
        }
    }

    if (ppName != NULL)
    {
        *ppName = duplicate_name(NULL, name);

        if (*ppName == NULL)
        {
            return E_OUTOFMEMORY;
        }
    }

    return S_OK;
}

static HRESULT WINAPI IWSDXMLContextImpl_SetNamespaces(IWSDXMLContext *iface, const PCWSDXML_NAMESPACE *pNamespaces, WORD wNamespacesCount, BYTE bLayerNumber)
{
    FIXME("(%p, %p, %d, %d)\n", iface, pNamespaces, wNamespacesCount, bLayerNumber);
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDXMLContextImpl_SetTypes(IWSDXMLContext *iface, const PCWSDXML_TYPE *pTypes, DWORD dwTypesCount, BYTE bLayerNumber)
{
    FIXME("(%p, %p, %d, %d)\n", iface, pTypes, dwTypesCount, bLayerNumber);
    return E_NOTIMPL;
}

static const IWSDXMLContextVtbl xmlcontext_vtbl =
{
    IWSDXMLContextImpl_QueryInterface,
    IWSDXMLContextImpl_AddRef,
    IWSDXMLContextImpl_Release,
    IWSDXMLContextImpl_AddNamespace,
    IWSDXMLContextImpl_AddNameToNamespace,
    IWSDXMLContextImpl_SetNamespaces,
    IWSDXMLContextImpl_SetTypes
};

HRESULT WINAPI WSDXMLCreateContext(IWSDXMLContext **ppContext)
{
    IWSDXMLContextImpl *obj;

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

    if (ppContext == NULL)
    {
        WARN("Invalid parameter: ppContext == NULL\n");
        return E_POINTER;
    }

    *ppContext = NULL;

    obj = WSDAllocateLinkedMemory(NULL, sizeof(*obj));

    if (!obj)
    {
        return E_OUTOFMEMORY;
    }

    obj->IWSDXMLContext_iface.lpVtbl = &xmlcontext_vtbl;
    obj->ref = 1;
    obj->namespaces = WSDAllocateLinkedMemory(obj, sizeof(struct list));
    obj->nextUnknownPrefix = 0;

    if (obj->namespaces == NULL)
    {
        WSDFreeLinkedMemory(obj);
        return E_OUTOFMEMORY;
    }

    list_init(obj->namespaces);

    *ppContext = &obj->IWSDXMLContext_iface;
    TRACE("Returning iface %p\n", *ppContext);

    return S_OK;
}
