/*
 * Copyright (C) 2008, 2014 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#ifndef DO_NO_IMPORTS
import "oaidl.idl";
import "ocidl.idl";
#endif

[
    object,
    oleautomation,
    hidden,
    uuid(9607001D-6EEF-4c2c-AD22-94E9DA587973),
    pointer_default(unique)
]
interface IWebCoreStatistics : IUnknown
{
    HRESULT javaScriptObjectsCount([out, retval] UINT* count);
    HRESULT javaScriptGlobalObjectsCount([out, retval] UINT* count);
    HRESULT javaScriptProtectedObjectsCount([out, retval] UINT* count);
    HRESULT javaScriptProtectedGlobalObjectsCount([out, retval] UINT* count);

    HRESULT iconPageURLMappingCount([out, retval] UINT* count);
    HRESULT iconRetainedPageURLCount([out, retval] UINT* count);
    HRESULT iconRecordCount([out, retval] UINT* count);
    HRESULT iconsWithDataCount([out, retval] UINT* count);

    HRESULT cachedFontDataCount([out, retval] UINT* count);
    HRESULT cachedFontDataInactiveCount([out, retval] UINT* count);
    HRESULT purgeInactiveFontData();
    HRESULT glyphPageCount([out, retval] UINT* count);

    HRESULT javaScriptProtectedObjectTypeCounts([out, retval] IPropertyBag2** typeNamesAndCounts);
    HRESULT javaScriptObjectTypeCounts([out, retval] IPropertyBag2** typeNamesAndCounts);

    HRESULT garbageCollectJavaScriptObjects();
    HRESULT garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging([in] BOOL waitUntilDone);
    HRESULT setJavaScriptGarbageCollectorTimerEnabled([in] BOOL);

    HRESULT shouldPrintExceptions([out, retval] BOOL*);
    HRESULT setShouldPrintExceptions([in] BOOL);

    HRESULT startIgnoringWebCoreNodeLeaks();
    HRESULT stopIgnoringWebCoreNodeLeaks();

    HRESULT memoryStatistics([out, retval] IPropertyBag** statistics);
    HRESULT returnFreeMemoryToSystem();

    HRESULT cachedPageCount([out, retval] INT* count);
    HRESULT cachedFrameCount([out, retval] INT* count);
}
