/*
    * BlockDevice.hpp
    * Driver-agnostic block device registry
    * Copyright (c) 2026 Daniel Hammer
*/

#pragma once
#include <cstdint>

namespace Drivers::Storage {

    static constexpr int MaxBlockDevices = 32;

    enum BlockDeviceKind : uint8_t {
        BLOCK_KIND_UNKNOWN = 0,
        BLOCK_KIND_SATA    = 1,
        BLOCK_KIND_SATAPI  = 2,
        BLOCK_KIND_NVME    = 3,
        BLOCK_KIND_USB_MSC = 4,
    };

    struct BlockDevice {
        bool (*ReadSectors)(void* ctx, uint64_t lba, uint32_t count, void* buffer);
        bool (*WriteSectors)(void* ctx, uint64_t lba, uint32_t count, const void* buffer);
        // Flush the device's volatile write cache to non-volatile media. Optional:
        // a null pointer means the device has no write-back cache to flush (so a
        // completed WriteSectors is already durable). Returns true on success.
        bool (*Flush)(void* ctx);
        void*    Ctx;
        uint64_t SectorCount;
        uint16_t SectorSize;
        uint8_t  Kind;
        uint8_t  Reserved;
        char     Model[41];
    };

    // Register a block device in the lowest free slot. Returns the assigned
    // index, or -1 on failure.
    int RegisterBlockDevice(const BlockDevice& dev);

    // Unregister a block device by index. Returns 0 on success, -1 on failure.
    int UnregisterBlockDevice(int index);

    // Get a registered block device by index. Returns nullptr if invalid.
    const BlockDevice* GetBlockDevice(int index);

    // Get the high-water count for registered block-device slots.
    int GetBlockDeviceCount();

};
