/*
 * Schema test
 *
 * Copyright 2007 Huw Davies
 *
 * 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 "windows.h"
#include "ole2.h"
#include "xmldom.h"
#include "msxml2.h"
#include <stdio.h>

#include "wine/test.h"

const CLSID CLSID_XMLSchemaCache      = {0x373984c9, 0xb845, 0x449b, {0x91, 0xe7, 0x45, 0xac, 0x83, 0x03, 0x6a, 0xde}};
const IID IID_IXMLDOMSchemaCollection = {0x373984c8, 0xb845, 0x449b, {0x91, 0xe7, 0x45, 0xac, 0x83, 0x03, 0x6a, 0xde}};

static const WCHAR schema_uri[] = {'x','-','s','c','h','e','m','a',':','t','e','s','t','.','x','m','l',0};

static const WCHAR schema_xml[] = {
    '<','S','c','h','e','m','a',' ','x','m','l','n','s','=','\"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','x','m','l','-','d','a','t','a','\"','\n',
    'x','m','l','n','s',':','d','t','=','\"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','d','a','t','a','t','y','p','e','s','\"','>','\n',
    '<','/','S','c','h','e','m','a','>','\n',0
};

static void test_schema_refs(void)
{
    IXMLDOMDocument2 *doc;
    IXMLDOMSchemaCollection *schema;
    HRESULT r;
    LONG ref;
    VARIANT v;
    VARIANT_BOOL b;
    BSTR str;

    r = CoCreateInstance( &CLSID_DOMDocument, NULL,
        CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
    if( r != S_OK )
        return;

    r = CoCreateInstance( &CLSID_XMLSchemaCache, NULL,
        CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (LPVOID*)&schema );
    if( r != S_OK )
    {
        IXMLDOMDocument2_Release(doc);
        return;
    }

    str = SysAllocString(schema_xml);
    r = IXMLDOMDocument2_loadXML(doc, str, &b);
    ok(r == S_OK, "ret %08x\n", r);
    ok(b == VARIANT_TRUE, "b %04x\n", b);
    SysFreeString(str);

    ref = IXMLDOMDocument2_AddRef(doc);
    ok(ref == 2, "ref %d\n", ref);
    VariantInit(&v);
    V_VT(&v) = VT_DISPATCH;
    V_DISPATCH(&v) = (IDispatch*)doc;

    str = SysAllocString(schema_uri);
    r = IXMLDOMSchemaCollection_add(schema, str, v);
    ok(r == S_OK, "ret %08x\n", r);

    /* IXMLDOMSchemaCollection_add doesn't add a ref on doc */
    ref = IXMLDOMDocument2_AddRef(doc);
    ok(ref == 3, "ref %d\n", ref);
    IXMLDOMDocument2_Release(doc);

    SysFreeString(str);
    VariantClear(&v);

    V_VT(&v) = VT_INT;
    r = IXMLDOMDocument2_get_schemas(doc, &v);
    ok(r == S_FALSE, "ret %08x\n", r);
    ok(V_VT(&v) == VT_NULL, "vt %x\n", V_VT(&v));

    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 2, "ref %d\n", ref);
    V_VT(&v) = VT_DISPATCH;
    V_DISPATCH(&v) = (IDispatch*)schema;

    /* check that putref_schemas takes a ref */
    r = IXMLDOMDocument2_putref_schemas(doc, v);
    ok(r == S_OK, "ret %08x\n", r);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 4, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);
    VariantClear(&v);

    /* refs now 2 */
    V_VT(&v) = VT_INT;
    /* check that get_schemas adds a ref */
    r = IXMLDOMDocument2_get_schemas(doc, &v);
    ok(r == S_OK, "ret %08x\n", r);
    ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v));
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 4, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);

    /* refs now 3 */
    /* get_schemas doesn't release a ref if passed VT_DISPATCH - ie it doesn't call VariantClear() */
    r = IXMLDOMDocument2_get_schemas(doc, &v);
    ok(r == S_OK, "ret %08x\n", r);
    ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v));
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 5, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);

    /* refs now 4 */
    /* release the two refs returned by get_schemas */
    IXMLDOMSchemaCollection_Release(schema);
    IXMLDOMSchemaCollection_Release(schema);

    /* refs now 2 */

    /* check that taking another ref on the document doesn't change the schema's ref count */
    IXMLDOMDocument2_AddRef(doc);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 3, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);
    IXMLDOMDocument2_Release(doc);


    /* refs now 2 */
    /* call putref_schema with some odd variants */
    V_VT(&v) = VT_INT;
    r = IXMLDOMDocument2_putref_schemas(doc, v);
    ok(r == E_FAIL, "ret %08x\n", r);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 3, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);

    /* refs now 2 */
    /* calling with VT_EMPTY releases the schema */
    V_VT(&v) = VT_EMPTY;
    r = IXMLDOMDocument2_putref_schemas(doc, v);
    ok(r == S_OK, "ret %08x\n", r);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 2, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);

    /* refs now 1 */
    /* try setting with VT_UNKNOWN */
    IXMLDOMSchemaCollection_AddRef(schema);
    V_VT(&v) = VT_UNKNOWN;
    V_UNKNOWN(&v) = (IUnknown*)schema;
    r = IXMLDOMDocument2_putref_schemas(doc, v);
    ok(r == S_OK, "ret %08x\n", r);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 4, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);
    VariantClear(&v);

    /* refs now 2 */
    /* calling with VT_NULL releases the schema */
    V_VT(&v) = VT_NULL;
    r = IXMLDOMDocument2_putref_schemas(doc, v);
    ok(r == S_OK, "ret %08x\n", r);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 2, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);

    /* refs now 1 */
    /* set again */
    IXMLDOMSchemaCollection_AddRef(schema);
    V_VT(&v) = VT_UNKNOWN;
    V_UNKNOWN(&v) = (IUnknown*)schema;
    r = IXMLDOMDocument2_putref_schemas(doc, v);
    ok(r == S_OK, "ret %08x\n", r);
    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 4, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);
    VariantClear(&v);

    /* refs now 2 */

    /* release the final ref on the doc which should release its ref on the schema */
    IXMLDOMDocument2_Release(doc);

    ref = IXMLDOMSchemaCollection_AddRef(schema);
    ok(ref == 2, "ref %d\n", ref);
    IXMLDOMSchemaCollection_Release(schema);
    IXMLDOMSchemaCollection_Release(schema);
}

START_TEST(schema)
{
    HRESULT r;

    r = CoInitialize( NULL );
    ok( r == S_OK, "failed to init com\n");

    test_schema_refs();

    CoUninitialize();
}
