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

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 {
    std::io::Read,
    crate::Result,
};

#[cfg(unix)]
use std::fs::File;

#[cfg(windows)]
mod windows;

/// #   Random
#[derive(Debug)]
pub (crate) struct Random {
    #[cfg(unix)]
    file: File,
}

impl Random {

    /// #   Makes new instance
    pub fn make() -> Result<Self> {
        Ok(Self {
            #[cfg(unix)]
            file: File::open("/dev/urandom")?,
        })
    }

    /// # Takes a next chunk
    pub fn next_chunk<const N: usize>(&mut self) -> Result<[u8; N]> {
        let mut result = [u8::MIN; N];

        #[cfg(unix)]
        self.file.read_exact(&mut result)?;

        #[cfg(windows)]
        windows::read_exact(&mut result)?;

        Ok(result)
    }

}

impl Read for Random {

    #[cfg(unix)]
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        self.file.read(buf)
    }

    #[cfg(windows)]
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        windows::read_exact(buf).map(|()| buf.len()).map_err(|e| e.into())
    }

}
