/*
 * 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";
import "windows.storage.streams.idl";

namespace Windows.Devices.Usb {
    interface IUsbDevice;
    interface IUsbDeviceClass;
    interface IUsbConfiguration;
    interface IUsbDeviceDescriptor;
    interface IUsbDeviceStatics;
    interface IUsbInterface;
    interface IUsbSetupPacket;
    interface IUsbSetupPacketFactory;

    runtimeclass UsbConfiguration;
    runtimeclass UsbDevice;
    runtimeclass UsbDeviceClass;
    runtimeclass UsbDeviceDescriptor;
    runtimeclass UsbInterface;
    runtimeclass UsbSetupPacket;

    declare {
        interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Devices.Usb.UsbDevice *>;
        interface Windows.Foundation.IAsyncOperation<Windows.Devices.Usb.UsbDevice *>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Usb.UsbDevice),
        uuid(5249b992-c456-44d5-ad5e-24f5a089f63b)
    ]
    interface IUsbDevice : IInspectable
        requires Windows.Foundation.IClosable
    {
        [overload("SendControlOutTransferAsync")]
        HRESULT SendControlOutTransferAsync(
            [in] Windows.Devices.Usb.UsbSetupPacket *packet,
            [in] Windows.Storage.Streams.IBuffer *buffer,
            [out, retval] Windows.Foundation.IAsyncOperation<UINT32> **operation
        );
        [overload("SendControlOutTransferAsync")]
        HRESULT SendControlOutTransferAsyncNoBuffer(
            [in] Windows.Devices.Usb.UsbSetupPacket *packet,
            [out, retval] Windows.Foundation.IAsyncOperation<UINT32> **operation
        );
        [overload("SendControlInTransferAsync")]
        HRESULT SendControlInTransferAsync(
            [in] Windows.Devices.Usb.UsbSetupPacket *packet,
            [in] Windows.Storage.Streams.IBuffer *buffer,
            [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.Streams.IBuffer *> **operation
        );
        [overload("SendControlInTransferAsync")]
        HRESULT SendControlInTransferAsyncNoBuffer(
            [in] Windows.Devices.Usb.UsbSetupPacket *packet,
            [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.Streams.IBuffer *> **operation
        );
        [propget] HRESULT DefaultInterface([out, retval] Windows.Devices.Usb.UsbInterface **value);
        [propget] HRESULT DeviceDescriptor([out, retval] Windows.Devices.Usb.UsbDeviceDescriptor **value);
        [propget] HRESULT Configuration([out, retval] Windows.Devices.Usb.UsbConfiguration **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Usb.UsbDeviceClass),
        uuid(051942f9-845e-47eb-b12a-38f2f617afe7)
    ]
    interface IUsbDeviceClass : IInspectable
    {
        [propget] HRESULT ClassCode([out, retval] BYTE *value);
        [propput] HRESULT ClassCode([in] BYTE value);
        [propget] HRESULT SubclassCode([out, retval] Windows.Foundation.IReference<BYTE> **value);
        [propput] HRESULT SubclassCode([in] Windows.Foundation.IReference<BYTE> *value);
        [propget] HRESULT ProtocolCode([out, retval] Windows.Foundation.IReference<BYTE> **value);
        [propput] HRESULT ProtocolCode([in] Windows.Foundation.IReference<BYTE> *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Usb.UsbDevice),
        uuid(066b85a2-09b7-4446-8502-6fe6dcaa7309)
    ]
    interface IUsbDeviceStatics : IInspectable
    {
        [overload("GetDeviceSelector")]
        HRESULT GetDeviceSelector([in] UINT32 vendor, [in] UINT32 product, [in] GUID class, [out, retval] HSTRING *value);
        [overload("GetDeviceSelector")]
        HRESULT GetDeviceSelectorGuidOnly([in] GUID class, [out, retval] HSTRING *value);
        [overload("GetDeviceSelector")]
        HRESULT GetDeviceSelectorVidPidOnly([in] UINT32 vendor, [in] UINT32 product, [out, retval] HSTRING *value);
        HRESULT GetDeviceClassSelector([in] Windows.Devices.Usb.UsbDeviceClass *class, [out, retval] HSTRING *value);
        HRESULT FromIdAsync([in] HSTRING id, [out, retval] Windows.Foundation.IAsyncOperation<Windows.Devices.Usb.UsbDevice *> **operation);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UsbConfiguration
    {
        [default] interface Windows.Devices.Usb.IUsbConfiguration;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.Devices.Usb.IUsbDeviceStatics, Windows.Foundation.UniversalApiContract, 1.0)
    ]
    runtimeclass UsbDevice
    {
        [default] interface Windows.Devices.Usb.IUsbDevice;
        interface Windows.Foundation.IClosable;
    }

    [
        activatable(Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UsbDeviceClass
    {
        [default] interface Windows.Devices.Usb.IUsbDeviceClass;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UsbDeviceDescriptor
    {
        [default] interface Windows.Devices.Usb.IUsbDeviceDescriptor;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UsbInterface
    {
        [default] interface Windows.Devices.Usb.IUsbInterface;
    }

    [
        activatable(Windows.Devices.Usb.IUsbSetupPacketFactory, Windows.Foundation.UniversalApiContract, 1.0),
        activatable(Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile)
    ]
    runtimeclass UsbSetupPacket
    {
        [default] interface Windows.Devices.Usb.IUsbSetupPacket;
    }
}
