/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

sluggish-write

Copyright (C) 2026  Anonymous



This program 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 3 of the License, or
(at your option) any later version.

This program 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 program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

use {
    core::mem,
    crate::{
        Result,
        random::Random,
    },
};

#[cfg(test)]
mod tests;

const KIB: usize = 1024;

/// #   Big buffer
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum BigBuf {

    /// #   4 KiB
    FourKiB,

    /// #   8 KiB
    EightKiB,

    /// #   16 KiB
    SixteenKiB,

    /// #   32 KiB
    ThirtyTwoKiB,

    /// #   64 KiB
    SixtyFourKiB,

}

impl BigBuf {

    /// #   All variants
    pub const fn all() -> &'static [Self; mem::variant_count::<Self>()] {
        &[Self::FourKiB, Self::EightKiB, Self::SixteenKiB, Self::ThirtyTwoKiB, Self::SixtyFourKiB]
    }

    /// #   Makes new random data the size of this buffer
    pub fn make(&self) -> Result<Vec<u8>> {
        const CHUNK_SIZE: usize = 512;

        let mut random = Random::make()?;

        let size = self.size();
        let mut result = Vec::with_capacity(size);
        for _ in usize::MIN..size / CHUNK_SIZE {
            result.extend(random.next_chunk::<CHUNK_SIZE>()?);
        }

        Ok(result)
    }

    /// #   Size
    pub const fn size(&self) -> usize {
        match self {
            Self::FourKiB => 4 * KIB,
            Self::EightKiB => 8 * KIB,
            Self::SixteenKiB => 16 * KIB,
            Self::ThirtyTwoKiB => 32 * KIB,
            Self::SixtyFourKiB => 64 * KIB,
        }
    }

}
