// Copyright 2025 Richard Hughes <richard@hughsie.com>
// SPDX-License-Identifier: LGPL-2.1-or-later

#[derive(ToString)]
enum FuNvmeStatus {
    // Generic Command Status:
    Success = 0x0,
    InvalidOpcode = 0x1,
    InvalidField = 0x2,
    CmdidConflict = 0x3,
    DataXferError = 0x4,
    PowerLoss = 0x5,
    Internal = 0x6,
    AbortReq = 0x7,
    AbortQueue = 0x8,
    FusedFail = 0x9,
    FusedMissing = 0xa,
    InvalidNs = 0xb,
    CmdSeqError = 0xc,
    SglInvalidLast = 0xd,
    SglInvalidCount = 0xe,
    SglInvalidData = 0xf,
    SglInvalidMetadata = 0x10,
    SglInvalidType = 0x11,

    SglInvalidOffset = 0x16,
    SglInvalidSubtype = 0x17,

    SanitizeFailed = 0x1c,
    SanitizeInProgress = 0x1d,

    NsWriteProtected = 0x20,

    LbaRange = 0x80,
    CapExceeded = 0x81,
    NsNotReady = 0x82,
    ReservationConflict = 0x83,

    // command specific status:
    CqInvalid = 0x100,
    QidInvalid = 0x101,
    QueueSize = 0x102,
    AbortLimit = 0x103,
    AbortMissing = 0x104,
    AsyncLimit = 0x105,
    FirmwareSlot = 0x106,
    FirmwareImage = 0x107,
    InvalidVector = 0x108,
    InvalidLogPage = 0x109,
    InvalidFormat = 0x10a,
    FwNeedsConvReset = 0x10b,
    InvalidQueue = 0x10c,
    FeatureNotSaveable = 0x10d,
    FeatureNotChangeable = 0x10e,
    FeatureNotPerNs = 0x10f,
    FwNeedsSubsysReset = 0x110,
    FwNeedsReset = 0x111,
    FwNeedsMaxTime = 0x112,
    FwActivateProhibited = 0x113,
    OverlappingRange = 0x114,
    NsInsufficentCap = 0x115,
    NsIdUnavailable = 0x116,
    NsAlreadyAttached = 0x118,
    NsIsPrivate = 0x119,
    NsNotAttached = 0x11a,
    ThinProvNotSupp = 0x11b,
    CtrlListInvalid = 0x11c,
    BpWriteProhibited = 0x11e,

    // i/o command set specific - nvm commands:
    BadAttributes = 0x180,
    InvalidPi = 0x181,
    ReadOnly = 0x182,
    OncsNotSupported = 0x183,

    DiscoveryRestart = 0x190,
    AuthRequired = 0x191,

    // media and data integrity errors:
    WriteFault = 0x280,
    ReadError = 0x281,
    GuardCheck = 0x282,
    ApptagCheck = 0x283,
    ReftagCheck = 0x284,
    CompareFailed = 0x285,
    AccessDenied = 0x286,
    UnwrittenBlock = 0x287,

    // path-related errors:
    AnaPersistentLoss = 0x301,
    AnaInaccessible = 0x302,
    AnaTransition = 0x303,

    Dnr = 0x4000,
}

#[derive(Parse)]
struct FuStructNvmeIdCtrl {
    vid: u16le,
    ssvid: u16le,
    sn: [char; 20],
    mn: [char; 40],
    fr: [char; 8],
    rab: u8,
    ieee: [u8; 3],
    cmic: u8,
    mdts: u8,
    cntlid: u16le,
    ver: u32le,
    rtd3r: u32le,
    rtd3e: u32le,
    oaes: u32le,
    ctratt: u32le,
    _rsvd100: [u8; 11],
    cntrltype: u8,
    fguid: Guid,
    crdt1: u16le,
    crdt2: u16le,
    crdt3: u16le,
    _rsvd134: [u8; 122],
    oacs: u16le,
    acl: u8,
    aerl: u8,
    frmw: u8,
    lpa: u8,
    elpe: u8,
    npss: u8,
    avscc: u8,
    apsta: u8,
    wctemp: u16le,
    cctemp: u16le,
    mtfa: u16le,
    hmpre: u32le,
    hmmin: u32le,
    tnvmcap: [u8; 16],
    unvmcap: [u8; 16],
    rpmbs: u32le,
    edstt: u16le,
    dsto: u8,
    fwug: u8,
    kas: u16le,
    hctma: u16le,
    mntmt: u16le,
    mxtmt: u16le,
    sanicap: u32le,
    hmminds: u32le,
    hmmaxd: u16le,
    nvmsetidmax: u16le,
    endgidmax: u16le,
    anatt: u8,
    anacap: u8,
    anagrpmax: u32le,
    nanagrpid: u32le,
    reserved: [u8; 3744],
}

#[derive(Parse)]
struct FuStructNvmeFwSlotInfoLog {
    afi: u8,
    _reserved1[]: [u8; 7],
    frs: [u64le; 7],
    _reserved2[]: [u8; 448],
}

#[derive(ToString)]
enum FuNvmeOpalFlags {
    Unknown = 0,
    Supported = 1 << 0,
    LockingSupported = 1 << 1,
    LockingEnabled = 1 << 2,
    Locked = 1 << 3,
    MbrEnabled = 1 << 4,
    MbrDone = 1 << 5,
    SumSupported = 1 << 6,
}
