/*
 * Copyright 2023 Rémi Bernon 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";
import "windows.storage.streams.idl";
import "windows.system.idl";

namespace Windows.System.Profile {
    typedef enum SystemIdentificationSource SystemIdentificationSource;
    interface IAnalyticsInfoStatics;
    interface IAnalyticsInfoStatics2;
    interface IAnalyticsVersionInfo;
    interface IAnalyticsVersionInfo2;
    interface ISystemIdentificationInfo;
    interface ISystemIdentificationStatics;
    runtimeclass AnalyticsVersionInfo;
    runtimeclass AnalyticsInfo;
    runtimeclass SystemIdentification;
    runtimeclass SystemIdentificationInfo;

    [contract(Windows.Foundation.UniversalApiContract, 3.0)]
    enum SystemIdentificationSource
    {
        None     = 0,
        Tpm      = 1,
        Uefi     = 2,
        [contract(Windows.Foundation.UniversalApiContract, 5.0)]
        Registry = 3,
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.System.Profile.AnalyticsInfo),
        uuid(1d5ee066-188d-5ba9-4387-acaeb0e7e305)
    ]
    interface IAnalyticsInfoStatics : IInspectable
    {
        [propget] HRESULT VersionInfo([out, retval] Windows.System.Profile.AnalyticsVersionInfo **value);
        [propget] HRESULT DeviceForm([out, retval] HSTRING *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.System.Profile.AnalyticsVersionInfo),
        uuid(926130b8-9955-4c74-bdc1-7cd0decf9b03)
    ]
    interface IAnalyticsVersionInfo : IInspectable
    {
        [propget] HRESULT DeviceFamily([out, retval] HSTRING *value);
        [propget] HRESULT DeviceFamilyVersion([out, retval] HSTRING *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.System.Profile.SystemIdentificationInfo),
        uuid(0c659e7d-c3c2-4d33-a2df-21bc41916eb3)
    ]
    interface ISystemIdentificationInfo : IInspectable
    {
        [propget] HRESULT Id([out, retval] Windows.Storage.Streams.IBuffer **value);
        [propget] HRESULT Source([out, retval] Windows.System.Profile.SystemIdentificationSource *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        exclusiveto(Windows.System.Profile.SystemIdentification),
        uuid(5581f42a-d3df-4d93-a37d-c41a616c6d01)
    ]
    interface ISystemIdentificationStatics : IInspectable
    {
        HRESULT GetSystemIdForPublisher([out, retval] Windows.System.Profile.SystemIdentificationInfo **result);
        HRESULT GetSystemIdForUser([in] Windows.System.User *user, [out, retval] Windows.System.Profile.SystemIdentificationInfo **result);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass AnalyticsVersionInfo
    {
        [default] interface Windows.System.Profile.IAnalyticsVersionInfo;
        /* [contract(Windows.Foundation.UniversalApiContract, 11.0)] interface Windows.System.Profile.IAnalyticsVersionInfo2; */
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.System.Profile.IAnalyticsInfoStatics, Windows.Foundation.UniversalApiContract, 1.0),
        /* static(Windows.System.Profile.IAnalyticsInfoStatics2, Windows.Foundation.UniversalApiContract, 6.0), */
        threading(both)
    ]
    runtimeclass AnalyticsInfo
    {
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        static(Windows.System.Profile.ISystemIdentificationStatics, Windows.Foundation.UniversalApiContract, 3.0),
        threading(both)
    ]
    runtimeclass SystemIdentification
    {
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 3.0),
        marshaling_behavior(agile),
        threading(both)
    ]
    runtimeclass SystemIdentificationInfo
    {
        [default] interface Windows.System.Profile.ISystemIdentificationInfo;
    }
}
