/*
 * Copyright (C) 2023 Mohamad Al-Jaf
 *
 * 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.Security.Isolation {
    typedef enum IsolatedWindowsEnvironmentHostError IsolatedWindowsEnvironmentHostError;

    interface IIsolatedWindowsEnvironmentHostStatics;

    runtimeclass IsolatedWindowsEnvironmentHost;

    declare {
        interface Windows.Foundation.Collections.IVectorView<Windows.Security.Isolation.IsolatedWindowsEnvironmentHostError>;
    }

    [
        contractversion(3.0)
    ]
    apicontract IsolatedWindowsEnvironmentContract
    {
    }

    [
        contract(Windows.Security.Isolation.IsolatedWindowsEnvironmentContract, 1.0)
    ]
    enum IsolatedWindowsEnvironmentHostError
    {
        AdminPolicyIsDisabledOrNotPresent = 0,
        FeatureNotInstalled               = 1,
        HardwareRequirementsNotMet        = 2,
        RebootRequired                    = 3,
        UnknownError                      = 4,
    };

    [
        contract(Windows.Security.Isolation.IsolatedWindowsEnvironmentContract, 1.0),
        exclusiveto(Windows.Security.Isolation.IsolatedWindowsEnvironmentHost),
        uuid(2c0e22c7-05a0-517a-b81c-6ee8790c381f)
    ]
    interface IIsolatedWindowsEnvironmentHostStatics : IInspectable
    {
        [propget] HRESULT IsReady([out, retval] boolean *value);
        [propget] HRESULT HostErrors([out, retval] Windows.Foundation.Collections.IVectorView<Windows.Security.Isolation.IsolatedWindowsEnvironmentHostError> **value);
    }

    [
        contract(Windows.Security.Isolation.IsolatedWindowsEnvironmentContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.Security.Isolation.IIsolatedWindowsEnvironmentHostStatics, Windows.Security.Isolation.IsolatedWindowsEnvironmentContract, 1.0),
        threading(both)
    ]
    runtimeclass IsolatedWindowsEnvironmentHost
    {
    }
}
