/*
 * Copyright (C) 2022 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";
/* import "windows.security.cryptography.core.idl"; */
import "windows.storage.streams.idl";
import "windows.system.idl";

namespace Windows.Security.Credentials {
    typedef enum KeyCredentialCreationOption KeyCredentialCreationOption;
    typedef enum KeyCredentialStatus KeyCredentialStatus;

    interface IKeyCredential;
    interface IKeyCredentialManagerStatics;
    interface IKeyCredentialRetrievalResult;

    runtimeclass KeyCredential;
    runtimeclass KeyCredentialManager;
    runtimeclass KeyCredentialRetrievalResult;

    declare {
        interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Security.Credentials.KeyCredentialRetrievalResult *>;
        interface Windows.Foundation.IAsyncOperation<Windows.Security.Credentials.KeyCredentialRetrievalResult *>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0)
    ]
    enum KeyCredentialCreationOption
    {
        ReplaceExisting = 0,
        FailIfExists    = 1,
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0)
    ]
    enum KeyCredentialStatus
    {
        Success                 = 0,
        UnknownError            = 1,
        NotFound                = 2,
        UserCanceled            = 3,
        UserPrefersPassword     = 4,
        CredentialAlreadyExists = 5,
        SecurityDeviceLocked    = 6,
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Security.Credentials.KeyCredentialManager),
        uuid(6aac468b-0ef1-4ce0-8290-4106da6a63b5)
    ]
    interface IKeyCredentialManagerStatics : IInspectable
    {
        HRESULT IsSupportedAsync([out, retval] Windows.Foundation.IAsyncOperation<boolean> **value);
        HRESULT RenewAttestationAsync([out, retval] Windows.Foundation.IAsyncAction **operation);
        HRESULT RequestCreateAsync(HSTRING name, Windows.Security.Credentials.KeyCredentialCreationOption option,
                                   [out, retval] Windows.Foundation.IAsyncOperation<Windows.Security.Credentials.KeyCredentialRetrievalResult *> **value);
        HRESULT OpenAsync(HSTRING name, [out, retval] Windows.Foundation.IAsyncOperation<Windows.Security.Credentials.KeyCredentialRetrievalResult *> **value);
        HRESULT DeleteAsync(HSTRING name, [out, retval] Windows.Foundation.IAsyncAction **operation);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Security.Credentials.KeyCredentialRetrievalResult),
        uuid(58cd7703-8d87-4249-9b58-f6598cc9644e)
    ]
    interface IKeyCredentialRetrievalResult : IInspectable
    {
        [propget] HRESULT Credential([out, retval] Windows.Security.Credentials.KeyCredential **value);
        [propget] HRESULT Status([out, retval] Windows.Security.Credentials.KeyCredentialStatus *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass KeyCredential
    {
        [default] interface Windows.Security.Credentials.IKeyCredential;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.Security.Credentials.IKeyCredentialManagerStatics, Windows.Foundation.UniversalApiContract, 1.0),
        threading(both)
    ]
    runtimeclass KeyCredentialManager
    {
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass KeyCredentialRetrievalResult
    {
        [default] interface Windows.Security.Credentials.IKeyCredentialRetrievalResult;
    }
}
