/*
 *    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 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_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 );
}
