/*
 *    MSXML Class Factory
 *
 * Copyright 2002 Lionel Ulmer
 * Copyright 2005 Mike McCormack
 *
 * 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 "msxml.h"
#include "msxml2.h"
#include "xmlparser.h"

/* undef the #define in msxml2 so that we can access the v.2 version
   independent CLSID as well as the v.3 one. */
#undef CLSID_DOMDocument

#include "wine/debug.h"

#include "msxml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

typedef HRESULT (*ClassFactoryCreateInstanceFunc)(IUnknown*, void**);
typedef HRESULT (*DOMFactoryCreateInstanceFunc)(MSXML_VERSION, IUnknown*, void**);

struct clsid_version_t
{
    const GUID *clsid;
    MSXML_VERSION version;
};

static const struct clsid_version_t clsid_versions_table[] =
{
    { &CLSID_DOMDocument,   MSXML_DEFAULT },
    { &CLSID_DOMDocument2,  MSXML2  },
    { &CLSID_DOMDocument26, MSXML26 },
    { &CLSID_DOMDocument30, MSXML3  },
    { &CLSID_DOMDocument40, MSXML4  },
    { &CLSID_DOMDocument60, MSXML6  },

    { &CLSID_DOMFreeThreadedDocument,   MSXML_DEFAULT },
    { &CLSID_FreeThreadedDOMDocument,   MSXML_DEFAULT },
    { &CLSID_FreeThreadedDOMDocument26, MSXML26 },
    { &CLSID_FreeThreadedDOMDocument30, MSXML3  },
    { &CLSID_FreeThreadedDOMDocument40, MSXML4  },
    { &CLSID_FreeThreadedDOMDocument60, MSXML6  },

    { &CLSID_XMLSchemaCache,   MSXML_DEFAULT },
    { &CLSID_XMLSchemaCache26, MSXML26 },
    { &CLSID_XMLSchemaCache30, MSXML3  },
    { &CLSID_XMLSchemaCache40, MSXML4  },
    { &CLSID_XMLSchemaCache60, MSXML6  },

    { &CLSID_MXXMLWriter,   MSXML_DEFAULT },
    { &CLSID_MXXMLWriter30, MSXML3 },
    { &CLSID_MXXMLWriter40, MSXML4 },
    { &CLSID_MXXMLWriter60, MSXML6 },

    { &CLSID_SAXXMLReader,   MSXML_DEFAULT },
    { &CLSID_SAXXMLReader30, MSXML3 },
    { &CLSID_SAXXMLReader40, MSXML4 },
    { &CLSID_SAXXMLReader60, MSXML6 },

    { &CLSID_SAXAttributes,   MSXML_DEFAULT },
    { &CLSID_SAXAttributes30, MSXML3 },
    { &CLSID_SAXAttributes40, MSXML4 },
    { &CLSID_SAXAttributes60, MSXML6 },

    { &CLSID_XMLView, MSXML_DEFAULT }
};

static MSXML_VERSION get_msxml_version(const GUID *clsid)
{
    int i;

    for (i = 0; i < sizeof(clsid_versions_table)/sizeof(struct clsid_version_t); i++)
        if (IsEqualGUID(clsid, clsid_versions_table[i].clsid))
            return clsid_versions_table[i].version;

    ERR("unknown clsid=%s\n", debugstr_guid(clsid));
    return MSXML_DEFAULT;
}

/******************************************************************************
 * MSXML ClassFactory
 */
typedef struct
{
    IClassFactory IClassFactory_iface;
    ClassFactoryCreateInstanceFunc pCreateInstance;
} ClassFactory;

typedef struct
{
    IClassFactory IClassFactory_iface;
    LONG ref;
    DOMFactoryCreateInstanceFunc pCreateInstance;
    MSXML_VERSION version;
} DOMFactory;

static inline ClassFactory *ClassFactory_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
}

static HRESULT WINAPI ClassFactory_QueryInterface(
    IClassFactory *iface,
    REFIID riid,
    void **ppobj )
{
    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IClassFactory))
    {
        IClassFactory_AddRef( iface );
        *ppobj = iface;
        return S_OK;
    }

    FIXME("interface %s not implemented\n", debugstr_guid(riid));
    *ppobj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface )
{
    return 2;
}

static ULONG WINAPI ClassFactory_Release(IClassFactory *iface )
{
    return 1;
}

static HRESULT WINAPI ClassFactory_CreateInstance(
    IClassFactory *iface,
    IUnknown *pOuter,
    REFIID riid,
    void **ppobj )
{
    ClassFactory *This = ClassFactory_from_IClassFactory(iface);
    IUnknown *punk;
    HRESULT r;

    TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );

    *ppobj = NULL;

    if (pOuter)
        return CLASS_E_NOAGGREGATION;

    r = This->pCreateInstance( pOuter, (void**) &punk );
    if (FAILED(r))
        return r;

    r = IUnknown_QueryInterface( punk, riid, ppobj );
    IUnknown_Release( punk );
    return r;
}

static HRESULT WINAPI ClassFactory_LockServer(
    IClassFactory *iface,
    BOOL dolock)
{
    FIXME("(%p)->(%d),stub!\n",iface,dolock);
    return S_OK;
}

static inline DOMFactory *DOMFactory_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, DOMFactory, IClassFactory_iface);
}

static ULONG WINAPI DOMClassFactory_AddRef(IClassFactory *iface )
{
    DOMFactory *This = DOMFactory_from_IClassFactory(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref = %u\n", This, ref);
    return ref;
}

static ULONG WINAPI DOMClassFactory_Release(IClassFactory *iface )
{
    DOMFactory *This = DOMFactory_from_IClassFactory(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p) ref = %u\n", This, ref);
    if(!ref) {
        heap_free(This);
    }
    return ref;
}

static HRESULT WINAPI DOMClassFactory_CreateInstance(
    IClassFactory *iface,
    IUnknown *pOuter,
    REFIID riid,
    void **ppobj )
{
    DOMFactory *This = DOMFactory_from_IClassFactory(iface);
    IUnknown *punk;
    HRESULT r;

    TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );

    *ppobj = NULL;

    if (pOuter)
        return CLASS_E_NOAGGREGATION;

    r = This->pCreateInstance( This->version, pOuter, (void**) &punk );
    if (FAILED(r))
        return r;

    r = IUnknown_QueryInterface( punk, riid, ppobj );
    IUnknown_Release( punk );
    return r;
}

static const struct IClassFactoryVtbl ClassFactoryVtbl =
{
    ClassFactory_QueryInterface,
    ClassFactory_AddRef,
    ClassFactory_Release,
    ClassFactory_CreateInstance,
    ClassFactory_LockServer
};

static const struct IClassFactoryVtbl DOMClassFactoryVtbl =
{
    ClassFactory_QueryInterface,
    DOMClassFactory_AddRef,
    DOMClassFactory_Release,
    DOMClassFactory_CreateInstance,
    ClassFactory_LockServer
};

static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv, DOMFactoryCreateInstanceFunc fnCreateInstance)
{
    DOMFactory *ret = heap_alloc(sizeof(DOMFactory));
    HRESULT hres;

    ret->IClassFactory_iface.lpVtbl = &DOMClassFactoryVtbl;
    ret->ref = 0;
    ret->version = get_msxml_version(clsid);
    ret->pCreateInstance = fnCreateInstance;

    hres = IClassFactory_QueryInterface(&ret->IClassFactory_iface, riid, ppv);
    if(FAILED(hres)) {
        heap_free(ret);
        *ppv = NULL;
    }
    return hres;
}

static ClassFactory xmldoccf = { { &ClassFactoryVtbl }, XMLDocument_create };
static ClassFactory httpreqcf = { { &ClassFactoryVtbl }, XMLHTTPRequest_create };
static ClassFactory serverhttp = { { &ClassFactoryVtbl }, ServerXMLHTTP_create };
static ClassFactory xsltemplatecf = { { &ClassFactoryVtbl }, XSLTemplate_create };
static ClassFactory mxnsmanagercf = { {&ClassFactoryVtbl }, MXNamespaceManager_create };
static ClassFactory xmlparsercf = { { &ClassFactoryVtbl }, XMLParser_create };
static ClassFactory xmlviewcf = { { &ClassFactoryVtbl }, XMLView_create };

/******************************************************************
 *		DllGetClassObject (MSXML3.@)
 */
HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
{
    IClassFactory *cf = NULL;

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

    if( IsEqualCLSID( rclsid, &CLSID_DOMDocument )  ||  /* Version indep. v 2.x */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) ||  /* Version indep. v 3.0 */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument26 )||  /* Version dep.   v 2.6 */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument30 )||  /* Version dep.   v 3.0 */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument40 )||  /* Version dep.   v 4.0 */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument60 ))   /* Version dep.   v 6.0 */
    {
        return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache )   ||
             IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache26 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache40 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache60 ))
    {
        return DOMClassFactory_Create(rclsid, riid, ppv, SchemaCache_create);
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) )
    {
        cf = &xmldoccf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_DOMFreeThreadedDocument )   ||   /* Version indep. v 2.x */
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument )   ||
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument26 ) ||
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument30 ) ||
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument40 ) ||
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument60 ))
    {
        return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
    }
    else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) ||
             IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) ||
             IsEqualCLSID( rclsid, &CLSID_SAXXMLReader40 ) ||
             IsEqualCLSID( rclsid, &CLSID_SAXXMLReader60 ))
    {
        return DOMClassFactory_Create(rclsid, riid, ppv, SAXXMLReader_create);
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLHTTPRequest ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLHTTP) ||
             IsEqualCLSID( rclsid, &CLSID_XMLHTTP26 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLHTTP30 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLHTTP40 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLHTTP60 ))
    {
        cf = &httpreqcf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_ServerXMLHTTP ) ||
             IsEqualCLSID( rclsid, &CLSID_ServerXMLHTTP30 ) ||
             IsEqualCLSID( rclsid, &CLSID_ServerXMLHTTP40 ) ||
             IsEqualCLSID( rclsid, &CLSID_ServerXMLHTTP60 ))
    {
        cf = &serverhttp.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XSLTemplate )   ||
             IsEqualCLSID( rclsid, &CLSID_XSLTemplate26 ) ||
             IsEqualCLSID( rclsid, &CLSID_XSLTemplate30 ) ||
             IsEqualCLSID( rclsid, &CLSID_XSLTemplate40 ) ||
             IsEqualCLSID( rclsid, &CLSID_XSLTemplate60 ))
    {
        cf = &xsltemplatecf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_MXXMLWriter )   ||
             IsEqualCLSID( rclsid, &CLSID_MXXMLWriter30 ) ||
             IsEqualCLSID( rclsid, &CLSID_MXXMLWriter40 ) ||
             IsEqualCLSID( rclsid, &CLSID_MXXMLWriter60 ) )
    {
        return DOMClassFactory_Create(rclsid, riid, ppv, MXWriter_create);
    }
    else if( IsEqualCLSID( rclsid, &CLSID_SAXAttributes) ||
             IsEqualCLSID( rclsid, &CLSID_SAXAttributes30 ) ||
             IsEqualCLSID( rclsid, &CLSID_SAXAttributes40 ) ||
             IsEqualCLSID( rclsid, &CLSID_SAXAttributes60 ))
    {
        return DOMClassFactory_Create(rclsid, riid, ppv, SAXAttributes_create);
    }
    else if( IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager ) ||
             IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager40 ) ||
             IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager60 ) )
    {
        cf = &mxnsmanagercf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLParser )  ||
             IsEqualCLSID( rclsid, &CLSID_XMLParser26 ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLParser30 )  )
    {
        cf = &xmlparsercf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLView ) )
    {
        cf = &xmlviewcf.IClassFactory_iface;
    }

    if ( !cf )
        return CLASS_E_CLASSNOTAVAILABLE;

    return IClassFactory_QueryInterface( cf, riid, ppv );
}
