use yggdrasil_abi::error::Error;

#[derive(Debug, Clone, Copy)]
pub enum TransferError {
    InvalidTransfer,
    ShortPacket(usize),
    BufferError,
    UsbTransactionError,
    Stall,
    Other(u8),
}

#[derive(Debug)]
pub enum UsbError {
    /// Could not allocate memory for some device structure
    MemoryError(Error),
    /// Other system errors
    SystemError(Error),
    // HC-side init stage errors
    OutOfAddresses,
    HostControllerCommandFailed(u8, u32),
    PortResetFailed,
    PortInitFailed,
    // Setup stage errors
    InvalidConfiguration,
    InvalidDescriptorField,
    // Runtime errors
    TimedOut,
    DeviceBusy,
    DeviceDisconnected,
    TransferFailed(TransferError),
    // Driver errors
    DriverError,
}

impl From<TransferError> for UsbError {
    fn from(value: TransferError) -> Self {
        Self::TransferFailed(value)
    }
}

impl From<UsbError> for Error {
    fn from(value: UsbError) -> Self {
        match value {
            UsbError::MemoryError(e) => e,
            e => {
                log::warn!("usb: {e:?}");
                Error::InvalidOperation
            }
        }
    }
}
