use std::cmp::min;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
#[derive(Copy, Clone, PartialEq, Eq)]
struct MemInfo {
        mem_total: usize,
        mem_free: usize,
        mem_available: usize,
}
fn get_memory_info() -> Option<MemInfo> {
    let lines = get_lines("/proc/meminfo")?;
    let mut lines = lines.iter();
    let mem_total: usize = match lines.next() {
        Some(line) => match line.split_whitespace().nth(1) {
            Some(val) => {
                let res = val.parse();
                if res.is_err() {
                    return None;
                }
                res.unwrap()
            }
            None => return None,
        },
        None => return None,
    };
    let mem_free: usize = match lines.next() {
        Some(line) => match line.split_whitespace().nth(1) {
            Some(val) => {
                let res = val.parse();
                if res.is_err() {
                    return None;
                }
                res.unwrap()
            }
            None => return None,
        },
        None => return None,
    };
    let mem_available: usize = match lines.next() {
        Some(line) => match line.split_whitespace().nth(1) {
            Some(val) => {
                let res = val.parse();
                if res.is_err() {
                    return None;
                }
                res.unwrap()
            }
            None => return None,
        },
        None => return None,
    };
    Some(MemInfo {
        mem_available,
        mem_free,
        mem_total,
    })
}
fn get_lines(filename: &str) -> Option<Vec<String>> {
    let f = File::open(filename);
    if f.is_err() {
        return None;
    }
    let f = f.unwrap();
    let file = BufReader::new(&f);
    let mut out_lines = Vec::new();
    for line in file.lines() {
        match line {
            Ok(val) => out_lines.push(val),
            Err(_) => break,
        }
    }
    Some(out_lines)
}
pub fn get_buffer_size() -> usize {
            const DEFAULT_BUFFER: usize = 10_000_000_000;
    if let Some(mem_status) = get_memory_info() {
        trace!("Successfully got memory info",);
                                                let mul_res = mem_status.mem_available.checked_mul(1000);
        match mul_res {
            Some(value) => {
                                                let div_res = value.checked_div(2);
                match div_res {
                    Some(value) => min(DEFAULT_BUFFER, value),
                    None => DEFAULT_BUFFER,
                }
            }
            None => DEFAULT_BUFFER,
        }
    } else {
        DEFAULT_BUFFER
    }
}