export type USBSpeed = 'low' | 'full' | 'high' | 'super' | 'superPlus';

export declare interface UsbDevice extends USBDevice {
    /**
     * The USB bus the device is connected to (e.g. `1-1`, `2-3.4`, etc.)
     */
    bus: string;

    /**
     * The USB address the device is connected to
     */
    address: number;

    /**
     * The USB port numbers the device is connected through (e.g. `[1]`, `[3, 4]`, etc.)
     */
    ports: Array<number>

    /**
     * The USB speed of the device (e.g. `Low`, `Full`, `High`, `Super`, `SuperPlus` or `undefined` if unknown)
     */
    speed?: USBSpeed;

    /**
     * Detaches the kernel driver from the specified interface number (Linux only)
     * @param interfaceNumber 
     */
    detachKernelDriver(interfaceNumber: number): Promise<void>;

    /**
     * Attaches the kernel driver for the specified interface number (Linux only)
     * @param interfaceNumber 
     */
    attachKernelDriver(interfaceNumber: number): Promise<void>;
}
export declare class Emitter {
  constructor()
  addAttach(callback: ((arg: UsbDevice) => void)): Promise<void>
  removeAttach(): Promise<void>
  addDetach(callback: ((arg: string) => void)): Promise<void>
  removeDetach(): Promise<void>
}

export declare class UsbDevice {
  vendorId: number
  productId: number
  deviceVersionMajor: number
  deviceVersionMinor: number
  deviceVersionSubminor: number
  usbVersionMajor: number
  usbVersionMinor: number
  usbVersionSubminor: number
  deviceClass: number
  deviceSubclass: number
  deviceProtocol: number
  bus: string
  address: number
  ports: Array<number>
  speed?: USBSpeed
  get handle(): string
  get manufacturerName(): string | null
  get productName(): string | null
  get serialNumber(): string | null
  get opened(): boolean
  get configuration(): USBConfiguration
  get configurations(): Array<USBConfiguration>
  open(): Promise<void>
  close(): Promise<void>
  forget(): Promise<void>
  reset(): Promise<void>
  selectConfiguration(configurationValue: number): Promise<void>
  claimInterface(interfaceNumber: number): Promise<void>
  releaseInterface(interfaceNumber: number): Promise<void>
  selectAlternateInterface(interfaceNumber: number, alternateSetting: number): Promise<void>
  nativeControlTransferIn(setup: USBControlTransferParameters, timeout: number, length: number): Promise<Uint8Array | null>
  nativeControlTransferOut(setup: USBControlTransferParameters, timeout: number, data?: Uint8Array | undefined | null): Promise<number>
  nativeTransferIn(endpointNumber: number, timeout: number, length: number): Promise<Uint8Array | null>
  nativeTransferOut(endpointNumber: number, timeout: number, data: Uint8Array): Promise<number>
  nativeIsochronousTransferIn(endpointNumber: number, packetLengths: Array<number>, timeout: number): Promise<USBIsochronousInTransferResult>
  nativeIsochronousTransferOut(endpointNumber: number, data: Uint8Array, packetLengths: Array<number>, timeout: number): Promise<USBIsochronousOutTransferResult>
  clearHalt(direction: USBDirection, endpointNumber: number): Promise<void>
  detachKernelDriver(interfaceNumber: number): Promise<void>
  attachKernelDriver(interfaceNumber: number): Promise<void>
}

export declare function nativeFindDeviceByIds(vendorId: number, productId: number): Promise<UsbDevice | null>

export declare function nativeFindDeviceBySerial(serialNumber: string): Promise<UsbDevice | null>

export declare function nativeGetDevices(): Promise<Array<UsbDevice>>

export interface UsbAlternateInterface {
  alternateSetting: number
  interfaceClass: number
  interfaceSubclass: number
  interfaceProtocol: number
  interfaceName?: string
  endpoints: Array<UsbEndpoint>
}

export interface UsbConfiguration {
  configurationValue: number
  configurationName?: string
  interfaces: Array<UsbInterface>
}

export interface USBControlTransferParameters {
  requestType: USBRequestType
  recipient: USBRecipient
  request: number
  value: number
  index: number
}

export interface UsbEndpoint {
  endpointNumber: number
  direction: USBDirection
  type: USBEndpointType
  packetSize: number
}

export interface UsbInterface {
  interfaceNumber: number
  claimed: boolean
  alternate: UsbAlternateInterface
  alternates: Array<UsbAlternateInterface>
}
