/*
 * tests for comcat functions
 *
 * Copyright 2006 Aric Stewart 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
 */

#define COBJMACROS

#include <stdio.h>
#include <initguid.h>
#include <windows.h>

#include "objbase.h"
#include "comcat.h"

#include "wine/test.h"

#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)

static BOOL register_testentry(void)
{
	HKEY hkey = 0, hkey2 = 0;
        DWORD ret;

        ret = RegCreateKeyA(HKEY_CLASSES_ROOT,"CLSID\\{deadcafe-beed-bead-dead-cafebeaddead}", &hkey);
        if (!ret) ret =	RegSetValueA(hkey,NULL,REG_SZ,"ComCat Test key",16);
	if (!ret) ret = RegCreateKeyA(hkey,
                                      "Implemented Categories\\{deadcafe-0000-0000-0000-000000000000}",
                                      &hkey2);
	RegCloseKey(hkey);
	RegCloseKey(hkey2);
        return !ret;
}

static void unregister_testentry(void)
{
	RegDeleteKeyA(HKEY_CLASSES_ROOT,
			"CLSID\\{deadcafe-beed-bead-dead-cafebeaddead}\\Implemented Categories\\{deadcafe-0000-0000-0000-000000000000}");
	RegDeleteKeyA(HKEY_CLASSES_ROOT,
			"CLSID\\{deadcafe-beed-bead-dead-cafebeaddead}\\Implemented Categories");
	RegDeleteKeyA(HKEY_CLASSES_ROOT,
			"CLSID\\{deadcafe-beed-bead-dead-cafebeaddead}");
}

static void do_enum(void)
{
	HRESULT hr;
	REFCLSID rclsid = &CLSID_StdComponentCategoriesMgr;
	ICatInformation *pICat = (ICatInformation*)0xdeadbeef;
	GUID the_guid[1];
	GUID the_cat[1];
	GUID wanted_guid;
	ULONG fetched = -1;

        static const WCHAR szCatID[] = {
			'{',
			'd','e','a','d','c','a','f','e',
			'-','0','0','0','0','-','0','0','0','0',
			'-','0','0','0','0',
			'-','0','0','0','0','0','0','0','0','0','0','0','0',
			'}',0};
        static const WCHAR szGuid[] = {
			'{',
			'd','e','a','d','c','a','f','e','-',
			'b','e','e','d','-',
			'b','e','a','d','-',
			'd','e','a','d','-',
			'c','a','f','e','b','e','a','d','d','e','a','d',
			'}',0};

	IEnumCLSID *pIEnum =(IEnumCLSID*)0xdeadcafe;

	CLSIDFromString(szCatID,the_cat);
	CLSIDFromString(szGuid,&wanted_guid);

	OleInitialize(NULL);

	hr = CoCreateInstance(rclsid,NULL,CLSCTX_INPROC_SERVER,
			&IID_ICatInformation, (void **)&pICat);
	ok_ole_success(hr, "CoCreateInstance");

	hr = ICatInformation_EnumClassesOfCategories(pICat, -1, NULL, -1, NULL,
			&pIEnum);
	ok_ole_success(hr,"ICatInformation_EnumClassesOfCategories");

	IEnumGUID_Release(pIEnum);
	
	hr = ICatInformation_EnumClassesOfCategories(pICat, 1, the_cat, -1, NULL, 
			&pIEnum);
	ok_ole_success(hr,"ICatInformation_EnumClassesOfCategories");

	hr = IEnumGUID_Next(pIEnum,1,the_guid, &fetched);
	ok (hr == S_FALSE,"Expected S_FALSE, got 0x%08x\n", hr);
	ok (fetched == 0,"Fetched wrong number of guids %u\n",fetched);
	IEnumGUID_Release(pIEnum);

	if (register_testentry())
        {
            hr = ICatInformation_EnumClassesOfCategories(pICat, 1, the_cat, -1, NULL, &pIEnum);
            ok_ole_success(hr,"ICatInformation_EnumClassesOfCategories");

            hr = IEnumGUID_Next(pIEnum,1,the_guid, &fetched);
            ok (hr == S_OK,"Expected S_OK, got 0x%08x\n", hr);
            ok (fetched == 1,"Fetched wrong number of guids %u\n",fetched);
            ok (IsEqualGUID(the_guid,&wanted_guid),"Guids do not match\n");

            IEnumGUID_Release(pIEnum);
            unregister_testentry();
        }
        else skip( "Could not register the test category\n" );

	ICatInformation_Release(pICat);

	OleUninitialize();
}


START_TEST(comcat)
{
 	do_enum(); 
}
