#![feature(yggdrasil_os, rustc_private)]

use std::{
    collections::VecDeque,
    fmt::Write
};

use libterm::{Clear, Term};
use libutil::fmt::FormatSize;
use yggdrasil_rt::system;

fn get_memory_stats() -> system::SystemMemoryStats {
    system::get_system_info!(system::MemoryUsage).unwrap()
}

fn main() {
    // Retrieve the stats once for total cap
    let stats = get_memory_stats();
    let total = stats.total_usable_pages;

    let mut term = Term::open().unwrap();

    let mut points = VecDeque::new();

    loop {
        let (width, height) = term.size().unwrap();
        term.clear(Clear::All).ok();

        let stats = get_memory_stats();

        points.push_back(stats.allocated_pages);

        let h = height - 1;

        for (i, point) in points.iter().enumerate() {
            let v = (*point * h) / total;
            for j in 0..v {
                term.set_cursor_position(h - j - 1, i).ok();
                term.write_char('*').ok();
            }
        }

        while points.len() >= width - 1 {
            points.pop_front();
        }

        term.set_cursor_position(h, 1).ok();

        let allocated_bytes = stats.allocated_pages * stats.page_size;
        let free_bytes = stats.free_pages * stats.page_size;
        let total_usable_bytes = stats.total_usable_pages * stats.page_size;

        let allocated_mem = FormatSize::default(allocated_bytes as u64);
        let free_mem = FormatSize::default(free_bytes as u64);
        let total_usable_mem = FormatSize::default(total_usable_bytes as u64);
        write!(
            term,
            "U: {} F: {} T: {} ({}%)",
            allocated_mem,
            free_mem,
            total_usable_mem,
            100 * stats.allocated_pages / stats.total_usable_pages
        )
        .ok();

        term.flush().ok();

        std::thread::sleep(std::time::Duration::from_millis(50));
    }
}
