/*
 * Copyright 2022 Zhiyi Zhang 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
 */

#ifdef __WIDL__
#pragma winrt ns_prefix
#endif

import "inspectable.idl";
import "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";

namespace Windows.Foundation.Metadata
{
    typedef enum GCPressureAmount GCPressureAmount;

    interface IApiInformationStatics;

    runtimeclass ApiInformation;

    [
        contract(Windows.Foundation.FoundationContract, 1.0)
    ]
    enum GCPressureAmount
    {
        Low    = 0,
        Medium = 1,
        High   = 2
    };

    [
        contract(Windows.Foundation.FoundationContract, 1.0),
        exclusiveto(Windows.Foundation.Metadata.ApiInformation),
        uuid(997439fe-f681-4a11-b416-c13a47e8ba36)
    ]
    interface IApiInformationStatics : IInspectable
    {
        HRESULT IsTypePresent([in] HSTRING type_name, [out, retval] boolean *value);
        [overload("IsMethodPresent")] HRESULT IsMethodPresent([in] HSTRING type_name, [in] HSTRING method_name, [out, retval] boolean *value);
        [overload("IsMethodPresent")] HRESULT IsMethodPresentWithArity([in] HSTRING type_name, [in] HSTRING method_name, [in] UINT32 parameter_count, [out, retval] boolean *value);
        HRESULT IsEventPresent([in] HSTRING type_name, [in] HSTRING event_name, [out, retval] boolean *value);
        HRESULT IsPropertyPresent([in] HSTRING type_name, [in] HSTRING property_name, [out, retval] boolean *value);
        HRESULT IsReadOnlyPropertyPresent([in] HSTRING type_name, [in] HSTRING property_name, [out, retval] boolean *value);
        HRESULT IsWriteablePropertyPresent([in] HSTRING type_name, [in] HSTRING property_name, [out, retval] boolean *value);
        HRESULT IsEnumNamedValuePresent([in] HSTRING enum_type_name, [in] HSTRING value_name, [out, retval] boolean *value);
        [overload("IsApiContractPresent")] HRESULT IsApiContractPresentByMajor([in] HSTRING contract_name, [in] UINT16 major_version, [out, retval] boolean *value);
        [overload("IsApiContractPresent")] HRESULT IsApiContractPresentByMajorAndMinor([in] HSTRING contract_name, [in] UINT16 major_version, [in] UINT16 minor_version, [out, retval] boolean *value);
    }

    [
        contract(Windows.Foundation.FoundationContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.Foundation.Metadata.IApiInformationStatics, Windows.Foundation.FoundationContract, 1.0),
        threading(both)
    ]
    runtimeclass ApiInformation
    {
    }
}
