/*
 * Configuration file parsing
 *
 * Copyright 2010 Vincent Povirk
 *
 * 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 <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "ole2.h"
#include "msxml2.h"
#include "mscoree.h"
#include "corhdr.h"
#include "metahost.h"
#include "cordebug.h"
#include "wine/list.h"
#include "mscoree_private.h"
#include "shlwapi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL( mscoree );

enum parse_state
{
    STATE_ASSEMBLY_BINDING,
    STATE_ROOT,
    STATE_CONFIGURATION,
    STATE_PROBING,
    STATE_RUNTIME,
    STATE_STARTUP,
    STATE_UNKNOWN
};

typedef struct ConfigFileHandler
{
    ISAXContentHandler ISAXContentHandler_iface;
    ISAXErrorHandler ISAXErrorHandler_iface;
    LONG ref;
    enum parse_state states[16];
    int statenum;
    parsed_config_file *result;
} ConfigFileHandler;

static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
{
    return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXContentHandler_iface);
}

static inline ConfigFileHandler *impl_from_ISAXErrorHandler(ISAXErrorHandler *iface)
{
    return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXErrorHandler_iface);
}

static HRESULT WINAPI ConfigFileHandler_QueryInterface(ISAXContentHandler *iface,
    REFIID riid, void **ppvObject)
{
    ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);

    if (IsEqualGUID(riid, &IID_ISAXContentHandler) || IsEqualGUID(riid, &IID_IUnknown))
        *ppvObject = &This->ISAXContentHandler_iface;
    else if (IsEqualGUID(riid, &IID_ISAXErrorHandler))
        *ppvObject = &This->ISAXErrorHandler_iface;
    else
    {
        WARN("Unsupported interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppvObject);

    return S_OK;
}

static ULONG WINAPI ConfigFileHandler_AddRef(ISAXContentHandler *iface)
{
    ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI ConfigFileHandler_Release(ISAXContentHandler *iface)
{
    ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
        HeapFree(GetProcessHeap(), 0, This);

    return ref;
}

static HRESULT WINAPI ConfigFileHandler_putDocumentLocator(ISAXContentHandler *iface,
    ISAXLocator *pLocator)
{
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_startDocument(ISAXContentHandler *iface)
{
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_endDocument(ISAXContentHandler *iface)
{
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_startPrefixMapping(ISAXContentHandler *iface,
    const WCHAR *pPrefix, int nPrefix, const WCHAR *pUri, int nUri)
{
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_endPrefixMapping(ISAXContentHandler *iface,
    const WCHAR *pPrefix, int nPrefix)
{
    return S_OK;
}

static HRESULT parse_startup(ConfigFileHandler *This, ISAXAttributes *pAttr)
{
    static const WCHAR legacy[] = {'u','s','e','L','e','g','a','c','y','V','2','R','u','n','t','i','m','e','A','c','t','i','v','a','t','i','o','n','P','o','l','i','c','y',0};
    static const WCHAR empty[] = {0};
    LPCWSTR value;
    int value_size;
    HRESULT hr;

    hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, legacy, lstrlenW(legacy), &value, &value_size);
    if (SUCCEEDED(hr))
        FIXME("useLegacyV2RuntimeActivationPolicy=%s not implemented\n", debugstr_wn(value, value_size));
    hr = S_OK;

    return hr;
}

static HRESULT parse_probing(ConfigFileHandler *This, ISAXAttributes *pAttr)
{
    static const WCHAR privatePath[] = {'p','r','i','v','a','t','e','P','a','t','h',0};
    static const WCHAR empty[] = {0};
    LPCWSTR value;
    int value_size;
    HRESULT hr;

    hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, privatePath, lstrlenW(privatePath), &value, &value_size);
    if (SUCCEEDED(hr))
        FIXME("privatePath=%s not implemented\n", debugstr_wn(value, value_size));
    hr = S_OK;

    return hr;
}


static HRESULT parse_supported_runtime(ConfigFileHandler *This, ISAXAttributes *pAttr)
{
    static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
    static const WCHAR sku[] = {'s','k','u',0};
    static const WCHAR empty[] = {0};
    LPCWSTR value;
    int value_size;
    HRESULT hr;
    supported_runtime *entry;

    hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, version, lstrlenW(version), &value, &value_size);
    if (SUCCEEDED(hr))
    {
        TRACE("%s\n", debugstr_wn(value, value_size));
        entry = HeapAlloc(GetProcessHeap(), 0, sizeof(supported_runtime));
        if (entry)
        {
            entry->version = HeapAlloc(GetProcessHeap(), 0, (value_size + 1) * sizeof(WCHAR));
            if (entry->version)
            {
                lstrcpyW(entry->version, value);
                list_add_tail(&This->result->supported_runtimes, &entry->entry);
            }
            else
            {
                HeapFree(GetProcessHeap(), 0, entry);
                hr = E_OUTOFMEMORY;
            }
        }
        else
            hr = E_OUTOFMEMORY;
    }
    else
        WARN("Missing version attribute\n");

    if (SUCCEEDED(hr))
    {
        hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, sku, lstrlenW(sku), &value, &value_size);
        if (SUCCEEDED(hr))
            FIXME("sku=%s not implemented\n", debugstr_wn(value, value_size));
        hr = S_OK;
    }

    return hr;
}

static HRESULT WINAPI ConfigFileHandler_startElement(ISAXContentHandler *iface,
    const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName,
    int nLocalName, const WCHAR *pQName, int nQName, ISAXAttributes *pAttr)
{
    ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);
    static const WCHAR configuration[] = {'c','o','n','f','i','g','u','r','a','t','i','o','n',0};
    static const WCHAR assemblyBinding[] = {'a','s','s','e','m','b','l','y','B','i','n','d','i','n','g',0};
    static const WCHAR probing[] = {'p','r','o','b','i','n','g',0};
    static const WCHAR runtime[] = {'r','u','n','t','i','m','e',0};
    static const WCHAR startup[] = {'s','t','a','r','t','u','p',0};
    static const WCHAR supportedRuntime[] = {'s','u','p','p','o','r','t','e','d','R','u','n','t','i','m','e',0};

    HRESULT hr = S_OK;

    TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri),
        debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName));

    if (This->statenum == sizeof(This->states) / sizeof(This->states[0]) - 1)
    {
        ERR("file has too much nesting\n");
        return E_FAIL;
    }

    switch (This->states[This->statenum])
    {
    case STATE_ROOT:
        if (nLocalName == sizeof(configuration)/sizeof(WCHAR)-1 &&
            lstrcmpW(pLocalName, configuration) == 0)
        {
            This->states[++This->statenum] = STATE_CONFIGURATION;
            break;
        }
        else
            goto unknown;
    case STATE_CONFIGURATION:
        if (nLocalName == sizeof(startup)/sizeof(WCHAR)-1 &&
            lstrcmpW(pLocalName, startup) == 0)
        {
            hr = parse_startup(This, pAttr);
            This->states[++This->statenum] = STATE_STARTUP;
            break;
        }
        else if (nLocalName == sizeof(runtime)/sizeof(WCHAR)-1 &&
            lstrcmpW(pLocalName, runtime) == 0)
        {
            This->states[++This->statenum] = STATE_RUNTIME;
            break;
        }
        else
            goto unknown;
    case STATE_RUNTIME:
        if (nLocalName == sizeof(assemblyBinding)/sizeof(WCHAR)-1 &&
            lstrcmpW(pLocalName, assemblyBinding) == 0)
        {
            This->states[++This->statenum] = STATE_ASSEMBLY_BINDING;
            break;
        }
        else
            goto unknown;
    case STATE_ASSEMBLY_BINDING:
        if (nLocalName == sizeof(probing)/sizeof(WCHAR)-1 &&
            lstrcmpW(pLocalName, probing) == 0)
        {
            hr = parse_probing(This, pAttr);
            This->states[++This->statenum] = STATE_PROBING;
            break;
        }
        else
            goto unknown;
    case STATE_STARTUP:
        if (nLocalName == sizeof(supportedRuntime)/sizeof(WCHAR)-1 &&
            lstrcmpW(pLocalName, supportedRuntime) == 0)
        {
            hr = parse_supported_runtime(This, pAttr);
            This->states[++This->statenum] = STATE_UNKNOWN;
            break;
        }
        else
            goto unknown;
    default:
        goto unknown;
    }

    return hr;

unknown:
    FIXME("Unknown element %s in state %u\n", debugstr_wn(pLocalName,nLocalName),
        This->states[This->statenum]);

    This->states[++This->statenum] = STATE_UNKNOWN;

    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_endElement(ISAXContentHandler *iface,
    const WCHAR *pNamespaceUri, int nNamespaceUri, const WCHAR *pLocalName,
    int nLocalName, const WCHAR *pQName, int nQName)
{
    ConfigFileHandler *This = impl_from_ISAXContentHandler(iface);

    TRACE("%s %s %s\n", debugstr_wn(pNamespaceUri,nNamespaceUri),
        debugstr_wn(pLocalName,nLocalName), debugstr_wn(pQName,nQName));

    if (This->statenum > 0)
    {
        This->statenum--;
    }
    else
    {
        ERR("element end does not match a start\n");
        return E_FAIL;
    }

    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_characters(ISAXContentHandler *iface,
    const WCHAR *pChars, int nChars)
{
    TRACE("%s\n", debugstr_wn(pChars,nChars));

    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_ignorableWhitespace(ISAXContentHandler *iface,
    const WCHAR *pChars, int nChars)
{
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_processingInstruction(ISAXContentHandler *iface,
    const WCHAR *pTarget, int nTarget, const WCHAR *pData, int nData)
{
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_skippedEntity(ISAXContentHandler *iface,
    const WCHAR * pName, int nName)
{
    TRACE("%s\n", debugstr_wn(pName,nName));
    return S_OK;
}

static const struct ISAXContentHandlerVtbl ConfigFileHandlerVtbl =
{
    ConfigFileHandler_QueryInterface,
    ConfigFileHandler_AddRef,
    ConfigFileHandler_Release,
    ConfigFileHandler_putDocumentLocator,
    ConfigFileHandler_startDocument,
    ConfigFileHandler_endDocument,
    ConfigFileHandler_startPrefixMapping,
    ConfigFileHandler_endPrefixMapping,
    ConfigFileHandler_startElement,
    ConfigFileHandler_endElement,
    ConfigFileHandler_characters,
    ConfigFileHandler_ignorableWhitespace,
    ConfigFileHandler_processingInstruction,
    ConfigFileHandler_skippedEntity
};

static HRESULT WINAPI ConfigFileHandler_Error_QueryInterface(ISAXErrorHandler *iface,
    REFIID riid, void **ppvObject)
{
    ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface);
    return ISAXContentHandler_QueryInterface(&This->ISAXContentHandler_iface, riid, ppvObject);
}

static ULONG WINAPI ConfigFileHandler_Error_AddRef(ISAXErrorHandler *iface)
{
    ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface);
    return ISAXContentHandler_AddRef(&This->ISAXContentHandler_iface);
}

static ULONG WINAPI ConfigFileHandler_Error_Release(ISAXErrorHandler *iface)
{
    ConfigFileHandler *This = impl_from_ISAXErrorHandler(iface);
    return ISAXContentHandler_Release(&This->ISAXContentHandler_iface);
}

static HRESULT WINAPI ConfigFileHandler_error(ISAXErrorHandler *iface,
    ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
{
    WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_fatalError(ISAXErrorHandler *iface,
    ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
{
    WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
    return S_OK;
}

static HRESULT WINAPI ConfigFileHandler_ignorableWarning(ISAXErrorHandler *iface,
    ISAXLocator * pLocator, const WCHAR * pErrorMessage, HRESULT hrErrorCode)
{
    WARN("%s,%x\n", debugstr_w(pErrorMessage), hrErrorCode);
    return S_OK;
}

static const struct ISAXErrorHandlerVtbl ConfigFileHandlerErrorVtbl =
{
    ConfigFileHandler_Error_QueryInterface,
    ConfigFileHandler_Error_AddRef,
    ConfigFileHandler_Error_Release,
    ConfigFileHandler_error,
    ConfigFileHandler_fatalError,
    ConfigFileHandler_ignorableWarning
};

static void init_config(parsed_config_file *config)
{
    list_init(&config->supported_runtimes);
}

static HRESULT parse_config(VARIANT input, parsed_config_file *result)
{
    ISAXXMLReader *reader;
    ConfigFileHandler *handler;
    HRESULT hr;

    handler = HeapAlloc(GetProcessHeap(), 0, sizeof(ConfigFileHandler));
    if (!handler)
        return E_OUTOFMEMORY;

    handler->ISAXContentHandler_iface.lpVtbl = &ConfigFileHandlerVtbl;
    handler->ISAXErrorHandler_iface.lpVtbl = &ConfigFileHandlerErrorVtbl;
    handler->ref = 1;
    handler->states[0] = STATE_ROOT;
    handler->statenum = 0;
    handler->result = result;

    hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
        &IID_ISAXXMLReader, (LPVOID*)&reader);

    if (SUCCEEDED(hr))
    {
        hr = ISAXXMLReader_putContentHandler(reader, &handler->ISAXContentHandler_iface);

        if (SUCCEEDED(hr))
            hr = ISAXXMLReader_putErrorHandler(reader, &handler->ISAXErrorHandler_iface);

        if (SUCCEEDED(hr))
            hr = ISAXXMLReader_parse(reader, input);

        ISAXXMLReader_Release(reader);
    }

    ISAXContentHandler_Release(&handler->ISAXContentHandler_iface);

    return S_OK;
}

HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result)
{
    IStream *stream;
    VARIANT var;
    HRESULT hr;
    HRESULT initresult;

    init_config(result);

    initresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    hr = SHCreateStreamOnFileW(filename, STGM_SHARE_DENY_WRITE | STGM_READ | STGM_FAILIFTHERE, &stream);

    if (SUCCEEDED(hr))
    {
        V_VT(&var) = VT_UNKNOWN;
        V_UNKNOWN(&var) = (IUnknown*)stream;

        hr = parse_config(var, result);

        IStream_Release(stream);
    }

    if (SUCCEEDED(initresult))
        CoUninitialize();

    return hr;
}

void free_parsed_config_file(parsed_config_file *file)
{
    supported_runtime *cursor, *cursor2;

    LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &file->supported_runtimes, supported_runtime, entry)
    {
        HeapFree(GetProcessHeap(), 0, cursor->version);
        list_remove(&cursor->entry);
        HeapFree(GetProcessHeap(), 0, cursor);
    }
}
