// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This program collects fine-grained memory stats around events of interest
// (such as browser tab discards) and saves them in a queue of "clip files",
// to be uploaded with other logs.
//
// The program has two modes: slow and fast poll.  In slow-poll mode, the
// program occasionally checks (every 2 seconds right now) whether it should go
// into fast-poll mode, because interesting events become possible.  When in
// fast-poll mode, the program collects memory stats frequently (every 0.1
// seconds right now) and stores them in a circular buffer.  When "interesting"
// events occur, the stats around each event are saved into a "clip" file.
// These files are also maintained as a queue, so only the latest N clips are
// available (N = 20 right now).

extern crate chrono;
extern crate dbus;
extern crate env_logger;
extern crate libc;
#[macro_use]
extern crate log;
extern crate syslog;
extern crate tempfile;

extern crate protobuf; // needed by proto_include.rs
include!(concat!(env!("OUT_DIR"), "/proto_include.rs"));

use chrono::prelude::*;
use {libc::__errno_location, libc::c_void};

#[cfg(not(test))]
use dbus::{BusType, Connection, WatchEvent};
#[cfg(not(test))]
use protobuf::Message;

use std::cmp::max;
use std::fmt;
use std::fs::{create_dir, File, OpenOptions};
use std::io::prelude::*;
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::{AsRawFd, RawFd};
use std::path::{Path, PathBuf};
#[cfg(not(test))]
use std::thread;
use std::{io, mem, str};
// Not to be confused with chrono::Duration or the deprecated time::Duration.
use std::time::Duration;
use tempfile::TempDir;

#[cfg(test)]
mod test;

const PAGE_SIZE: usize = 4096; // old friend

const LOG_DIRECTORY: &str = "/var/log/memd";
const STATIC_PARAMETERS_LOG: &str = "memd.parameters";
const LOW_MEM_SYSFS: &str = "/sys/kernel/mm/chromeos-low_mem";
const LOW_MEM_DEVICE: &str = "/dev/chromeos-low-mem";
const MAX_CLIP_COUNT: usize = 20;

const COLLECTION_DELAY_MS: i64 = 5_000; // Wait after event of interest.
const CLIP_COLLECTION_SPAN_MS: i64 = 10_000; // ms worth of samples in a clip.
const SAMPLES_PER_SECOND: i64 = 10; // Rate of fast sample collection.
const SAMPLING_PERIOD_MS: i64 = 1000 / SAMPLES_PER_SECOND;
// Danger threshold.  When the distance between "available" and "margin" is
// greater than LOW_MEM_DANGER_THRESHOLD_MB, we assume that there's no danger
// of "interesting" events (such as a discard) happening in the next
// SLOW_POLL_PERIOD_DURATION.  In other words, we expect that an allocation of
// more than LOW_MEM_DANGER_THRESHOLD_MB in a SLOW_POLL_PERIOD_DURATION will be
// rare.
const LOW_MEM_DANGER_THRESHOLD_MB: u32 = 600; // Poll fast when closer to margin than this.
const SLOW_POLL_PERIOD_DURATION: Duration = Duration::from_secs(2); // Sleep in slow-poll mode.
const FAST_POLL_PERIOD_DURATION: Duration = Duration::from_millis(SAMPLING_PERIOD_MS as u64); // Sleep duration in fast-poll mode.

// Print a warning if the fast-poll select lasts a lot longer than expected
// (which might happen because of huge load average and swap activity).
const UNREASONABLY_LONG_SLEEP: i64 = 10 * SAMPLING_PERIOD_MS;

// Size of sample queue.  The queue contains mostly timer events, in the amount
// determined by the clip span and the sampling rate.  It also contains other
// events, such as OOM kills etc., whose amount is expected to be smaller than
// the former.  Generously double the number of timer events to leave room for
// non-timer events.
const SAMPLE_QUEUE_LENGTH: usize =
    (CLIP_COLLECTION_SPAN_MS / 1000 * SAMPLES_PER_SECOND * 2) as usize;

// The names of fields of interest in /proc/vmstat.  They must be listed in
// the order in which they appear in /proc/vmstat.  When parsing the file,
// if a mandatory field is missing, the program panics.  A missing optional
// field (for instance, pgmajfault_f for some kernels) results in a value
// of 0. (BAD: This works only for the last field.)
//
// For fields with |accumulate| = true, use the name as a prefix, and add up
// all values with that prefix in consecutive lines.
const VMSTAT_VALUES_COUNT: usize = 5; // Number of vmstat values we're tracking.
#[rustfmt::skip]
const VMSTATS: [(&str, bool, bool); VMSTAT_VALUES_COUNT] = [
    // name                 mandatory   accumulate
    ("pswpin",              true, 	false),
    ("pswpout",             true,       false),
    ("pgalloc",             true,       true),   // pgalloc_dma, pgalloc_normal, etc.
    ("pgmajfault",          true,       false),
    ("pgmajfault_f",        false,      false),
];
// The only difference from x86_64 is pgalloc_dma vs. pgalloc_dma32.

#[derive(Debug)]
pub enum Error {
    LowMemFileError(Box<dyn std::error::Error>),
    VmstatFileError(Box<std::io::Error>),
    RunnablesFileError(Box<std::io::Error>),
    AvailableFileError(Box<dyn std::error::Error>),
    CreateLogDirError(Box<std::io::Error>),
    StartingClipCounterMissingError(Box<dyn std::error::Error>),
    LogStaticParametersError(Box<dyn std::error::Error>),
    DbusWatchError(Box<dyn std::error::Error>),
    LowMemFDWatchError(Box<dyn std::error::Error>),
    LowMemWatcherError(Box<dyn std::error::Error>),
}

impl std::error::Error for Error {
    // This function is "soft-deprecated" so
    // we use the fmt() function from Display below.
    fn description(&self) -> &str {
        "memd_error"
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::LowMemFileError(ref e) => write!(f, "cannot opening low-mem file: {}", e),
            &Error::VmstatFileError(ref e) => write!(f, "cannot open vmstat: {}", e),
            &Error::RunnablesFileError(ref e) => write!(f, "cannot open loadavg: {}", e),
            &Error::AvailableFileError(ref e) => write!(f, "cannot open available file: {}", e),
            &Error::CreateLogDirError(ref e) => write!(f, "cannot create log directory: {}", e),
            &Error::StartingClipCounterMissingError(ref e) => {
                write!(f, "cannot find starting clip counter: {}", e)
            }
            &Error::LogStaticParametersError(ref e) => {
                write!(f, "cannot log static parameters: {}", e)
            }
            &Error::DbusWatchError(ref e) => write!(f, "cannot watch dbus fd: {}", e),
            &Error::LowMemFDWatchError(ref e) => write!(f, "cannot watch low-mem fd: {}", e),
            &Error::LowMemWatcherError(ref e) => write!(f, "cannot set low-mem watcher: {}", e),
        }
    }
}

type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

fn errno() -> i32 {
    // _errno_location() is trivially safe to call and dereferencing the
    // returned pointer is always safe because it's guaranteed to be valid and
    // point to thread-local data.  (Thanks to Zach for this comment.)
    unsafe { *__errno_location() }
}

// Returns the string for posix error number |err|.
fn strerror(err: i32) -> String {
    // safe to leave |buffer| uninitialized because we initialize it from strerror_r.
    let mut buffer: [u8; PAGE_SIZE] = unsafe { mem::uninitialized() };
    // |err| is valid because it is the libc errno at all call sites.  |buffer|
    // is converted to a valid address, and |buffer.len()| is a valid length.
    let n = unsafe {
        libc::strerror_r(
            err,
            &mut buffer[0] as *mut u8 as *mut libc::c_char,
            buffer.len(),
        )
    } as usize;
    match str::from_utf8(&buffer[..n]) {
        Ok(s) => s.to_string(),
        Err(e) => {
            // Ouch---an error while trying to process another error.
            // Very unlikely so we just panic.
            panic!("error {:?} converting {:?}", e, &buffer[..n]);
        }
    }
}

// Opens a file if it exists, otherwise returns none.
fn open_maybe(path: &Path) -> Result<Option<File>> {
    if !path.exists() {
        Ok(None)
    } else {
        Ok(Some(File::open(path)?))
    }
}

// Opens a file with mode flags.  If the file does not exist, returns None.
fn open_with_flags_maybe(path: &Path, options: &OpenOptions) -> Result<Option<File>> {
    if !path.exists() {
        Ok(None)
    } else {
        Ok(Some(options.open(&path)?))
    }
}

// Converts the result of an integer expression |e| to modulo |n|. |e| may be
// negative. This differs from plain "%" in that the result of this function
// is always be between 0 and n-1.
fn modulo(e: isize, n: usize) -> usize {
    let nn = n as isize;
    let x = e % nn;
    (if x >= 0 { x } else { x + nn }) as usize
}

// Reads a string from the file named by |path|, representing a u32, and
// returns the value the strings it represents. If there are multiple ints
// in the file, then it returns the first one.
fn read_int(path: &Path) -> Result<u32> {
    let mut file = File::open(path)?;
    let mut content = String::new();
    file.read_to_string(&mut content)?;
    Ok(content
        .trim()
        .split_whitespace()
        .into_iter()
        .next()
        .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "empty file"))?
        .parse::<u32>()?)
}

// The Timer trait allows us to mock time for testing.
trait Timer {
    // A wrapper for libc::select() with only ready-to-read fds.
    fn select(
        &mut self,
        nfds: libc::c_int,
        fds: &mut libc::fd_set,
        timeout: &Duration,
    ) -> libc::c_int;
    fn sleep(&mut self, sleep_time: &Duration);
    fn now(&self) -> i64;
    fn quit_request(&self) -> bool;
}

#[cfg(not(test))]
struct GenuineTimer {}

#[cfg(not(test))]
impl Timer for GenuineTimer {
    // Returns current uptime (active time since boot, in milliseconds)
    fn now(&self) -> i64 {
        let mut ts: libc::timespec;
        // clock_gettime is safe when passed a valid address and a valid enum.
        let result = unsafe {
            ts = mem::uninitialized();
            libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts as *mut libc::timespec)
        };
        assert_eq!(result, 0, "clock_gettime() failed!");
        ts.tv_sec as i64 * 1000 + ts.tv_nsec as i64 / 1_000_000
    }

    // Always returns false, unless testing (see MockTimer).
    fn quit_request(&self) -> bool {
        false
    }

    fn sleep(&mut self, sleep_time: &Duration) {
        thread::sleep(*sleep_time);
    }

    fn select(
        &mut self,
        high_fd: i32,
        inout_read_fds: &mut libc::fd_set,
        timeout: &Duration,
    ) -> i32 {
        let mut libc_timeout = libc::timeval {
            tv_sec: timeout.as_secs() as libc::time_t,
            tv_usec: (timeout.subsec_nanos() / 1000) as libc::suseconds_t,
        };
        let null = std::ptr::null_mut();
        // Safe because we're passing valid values and addresses.
        unsafe {
            libc::select(
                high_fd,
                inout_read_fds,
                null,
                null,
                &mut libc_timeout as *mut libc::timeval,
            )
        }
    }
}

struct FileWatcher {
    read_fds: libc::fd_set,
    inout_read_fds: libc::fd_set,
    max_fd: i32,
}

// Interface to the select(2) system call, for ready-to-read only.
impl FileWatcher {
    fn new() -> FileWatcher {
        // The fd sets don't need to be initialized to known values because
        // they are cleared by the following FD_ZERO calls, which are safe
        // because we're passing libc::fd_sets to them.
        let mut read_fds = unsafe { mem::uninitialized::<libc::fd_set>() };
        let mut inout_read_fds = unsafe { mem::uninitialized::<libc::fd_set>() };
        unsafe {
            libc::FD_ZERO(&mut read_fds);
        };
        unsafe {
            libc::FD_ZERO(&mut inout_read_fds);
        };
        FileWatcher {
            read_fds,
            inout_read_fds,
            max_fd: -1,
        }
    }

    fn set(&mut self, f: &File) -> Result<()> {
        self.set_fd(f.as_raw_fd())
    }

    // The ..._fd functions exist because other APIs (e.g. dbus) return RawFds
    // instead of Files.
    fn set_fd(&mut self, fd: RawFd) -> Result<()> {
        if fd >= libc::FD_SETSIZE as i32 {
            return Err("set_fd: fd too large".into());
        }
        // see comment for |set()|
        unsafe {
            libc::FD_SET(fd, &mut self.read_fds);
        }
        self.max_fd = max(self.max_fd, fd);
        Ok(())
    }

    fn clear_fd(&mut self, fd: RawFd) -> Result<()> {
        if fd >= libc::FD_SETSIZE as i32 {
            return Err("clear_fd: fd is too large".into());
        }
        // see comment for |set()|
        unsafe {
            libc::FD_CLR(fd, &mut self.read_fds);
        }
        Ok(())
    }

    // Mut self here and below are required (unnecessarily) by FD_ISSET.
    fn has_fired(&mut self, f: &File) -> Result<bool> {
        self.has_fired_fd(f.as_raw_fd())
    }

    fn has_fired_fd(&mut self, fd: RawFd) -> Result<bool> {
        if fd >= libc::FD_SETSIZE as i32 {
            return Err("has_fired_fd: fd is too large".into());
        }
        // see comment for |set()|
        Ok(unsafe { libc::FD_ISSET(fd, &mut self.inout_read_fds) })
    }

    fn watch(&mut self, timeout: &Duration, timer: &mut dyn Timer) -> Result<usize> {
        self.inout_read_fds = self.read_fds;
        let n = timer.select(self.max_fd + 1, &mut self.inout_read_fds, &timeout);
        match n {
            // into() puts the io::Error in a Box.
            -1 => Err(io::Error::last_os_error().into()),
            n => {
                if n < 0 {
                    Err(format!("unexpected return value {} from select", n).into())
                } else {
                    Ok(n as usize)
                }
            }
        }
    }
}

#[derive(Clone, Copy, Default)]
struct Sample {
    uptime: i64, // system uptime in ms
    sample_type: SampleType,
    info: Sysinfo,
    runnables: u32, // number of runnable processes
    available: u32, // available RAM from low-mem notifier
    vmstat_values: [u64; VMSTAT_VALUES_COUNT],
}

impl Sample {
    // Outputs a sample.
    fn output(&self, out: &mut File) -> Result<()> {
        writeln!(
            out,
            "{}.{:02} {:6} {} {} {} {} {} {} {} {} {} {} {}",
            self.uptime / 1000,
            self.uptime % 1000 / 10,
            self.sample_type,
            self.info.0.loads[0],
            self.info.0.freeram,
            self.info.0.freeswap,
            self.info.0.procs,
            self.runnables,
            self.available,
            self.vmstat_values[0],
            self.vmstat_values[1],
            self.vmstat_values[2],
            self.vmstat_values[3],
            self.vmstat_values[4],
        )?;
        Ok(())
    }
}

#[derive(Copy, Clone)]
struct Sysinfo(libc::sysinfo);

impl Sysinfo {
    // Wrapper for sysinfo syscall.
    fn sysinfo() -> Result<Sysinfo> {
        let mut info: Sysinfo = Default::default();
        // sysinfo() is always safe when passed a valid pointer
        match unsafe { libc::sysinfo(&mut info.0 as *mut libc::sysinfo) } {
            0 => Ok(info),
            _ => Err(format!("sysinfo: {}", strerror(errno())).into()),
        }
    }

    // Fakes sysinfo system call, for testing.
    fn fake_sysinfo() -> Result<Sysinfo> {
        let mut info: Sysinfo = Default::default();
        // Any numbers will do.
        info.0.loads[0] = 5;
        info.0.freeram = 42_000_000;
        info.0.freeswap = 84_000_000;
        info.0.procs = 1234;
        Ok(info)
    }
}

impl Default for Sysinfo {
    fn default() -> Sysinfo {
        // safe because sysinfo contains only numbers
        unsafe { mem::zeroed() }
    }
}

struct SampleQueue {
    samples: [Sample; SAMPLE_QUEUE_LENGTH],
    head: usize,  // points to latest entry
    count: usize, // count of valid entries (min=0, max=SAMPLE_QUEUE_LENGTH)
}

impl SampleQueue {
    fn new() -> SampleQueue {
        let s: Sample = Default::default();
        SampleQueue {
            samples: [s; SAMPLE_QUEUE_LENGTH],
            head: 0,
            count: 0,
        }
    }

    // Returns self.head as isize, to make index calculations behave correctly
    // on underflow.
    fn ihead(&self) -> isize {
        self.head as isize
    }

    fn reset(&mut self) {
        self.head = 0;
        self.count = 0;
    }

    // Returns the next slot in the queue.  Always succeeds, since on overflow
    // it discards the LRU slot.
    fn next_slot(&mut self) -> &mut Sample {
        let slot = self.head;
        self.head = modulo(self.ihead() + 1, SAMPLE_QUEUE_LENGTH) as usize;
        if self.count < SAMPLE_QUEUE_LENGTH {
            self.count += 1;
        }
        &mut self.samples[slot]
    }

    fn sample(&self, i: isize) -> &Sample {
        assert!(i >= 0);
        // Subtract 1 because head points to the next free slot.
        assert!(
            modulo(self.ihead() - 1 - i, SAMPLE_QUEUE_LENGTH) <= self.count,
            "bad queue index: i {}, head {}, count {}, queue len {}",
            i,
            self.head,
            self.count,
            SAMPLE_QUEUE_LENGTH
        );
        &self.samples[i as usize]
    }

    // Outputs to file |f| samples from |start_time| to the head.  Uses a start
    // time rather than a start index because when we start a clip we have to
    // do a time-based search anyway.
    fn output_from_time(&self, mut f: &mut File, start_time: i64) -> Result<()> {
        // For now just do a linear search. ;)
        let mut start_index = modulo(self.ihead() - 1, SAMPLE_QUEUE_LENGTH);
        debug!(
            "output_from_time: start_time {}, head {}",
            start_time, start_index
        );
        loop {
            let sample = self.samples[start_index];
            // Ignore samples from external sources because their time stamp may be off.
            if sample.uptime <= start_time && sample.sample_type.has_internal_timestamp() {
                break;
            }
            debug!(
                "output_from_time: seeking uptime {}, index {}",
                sample.uptime, start_index
            );
            start_index = modulo(start_index as isize - 1, SAMPLE_QUEUE_LENGTH);
            if modulo(self.ihead() - 1 - start_index as isize, SAMPLE_QUEUE_LENGTH) > self.count {
                warn!("too many events in requested interval");
                break;
            }
        }

        let mut index = modulo(start_index as isize + 1, SAMPLE_QUEUE_LENGTH) as isize;
        while index != self.ihead() {
            debug!("output_from_time: outputting index {}", index);
            self.sample(index).output(&mut f)?;
            index = modulo(index + 1, SAMPLE_QUEUE_LENGTH) as isize;
        }
        Ok(())
    }
}

// Returns number of tasks in the run queue as reported in /proc/loadavg, which
// must be accessible via runnables_file.
pub fn get_runnables(runnables_file: &File) -> Result<u32> {
    // It is safe to leave the content of buffer uninitialized because we read
    // into it and only look at the part of it initialized by reading.
    let mut buffer: [u8; PAGE_SIZE] = unsafe { mem::uninitialized() };
    let content = pread(runnables_file, &mut buffer[..])?;
    // Example: "0.81 0.66 0.86 22/3873 7043" (22 runnables here).
    let slash_pos = content.find('/').ok_or_else(|| "cannot find '/'")?;
    let space_pos = &content[..slash_pos]
        .rfind(' ')
        .ok_or_else(|| "cannot find ' '")?;
    let (value, _) = parse_int_prefix(&content[space_pos + 1..])?;
    Ok(value)
}

// Converts the initial digit characters of |s| to the value of the number they
// represent.  Returns the number of characters scanned.
fn parse_int_prefix(s: &str) -> Result<(u32, usize)> {
    let mut result = 0;
    let mut count = 0;
    // Skip whitespace first.
    for c in s.trim_start().chars() {
        let x = c.to_digit(10);
        match x {
            Some(d) => {
                result = result * 10 + d;
                count += 1;
            }
            None => {
                break;
            }
        }
    }
    if count == 0 {
        Err(format!("parse_int_prefix: not an int: {}", s).into())
    } else {
        Ok((result, count))
    }
}

// Reads selected values from |file| (which should be opened to /proc/vmstat)
// as specified in |VMSTATS|, and stores them in |vmstat_values|.  The format of
// the vmstat file is (<name> <integer-value>\n)+.
fn get_vmstats(file: &File, vmstat_values: &mut [u64]) -> Result<()> {
    // Safe because we read into the buffer, then borrow the part of it that
    // was filled.
    let mut buffer: [u8; PAGE_SIZE] = unsafe { mem::uninitialized() };
    let content = pread(file, &mut buffer[..])?;
    let mut lines = content.split('\n');
    let mut targets = VMSTATS.iter().enumerate();
    let mut line = None;
    let mut target = None;
    let mut advance_line = true;
    let mut advance_target = true;
    for i in 0..VMSTAT_VALUES_COUNT {
        vmstat_values[i] = 0;
    }
    loop {
        if advance_target {
            target = targets.next();
            if target == None {
                break;
            }
        }
        if advance_line {
            line = lines.next();
            // Special case: empty last line.
            if line.is_some() && line.unwrap() == "" {
                line = None;
            }
            if line.is_none() {
                break;
            }
        }

        // The default is to advance the line and keep the same target.  When a
        // target is found in a line, the target is advanced, unless it's an
        // accumulated target, which adds up the values from consecutive
        // matching lines.
        advance_line = true;
        advance_target = false;

        let (i, &(wanted_name, mandatory, accumulate)) = target.unwrap();
        match line {
            Some(string) => {
                let mut pair = string.split(' ');
                let found_name = pair.next().ok_or_else(|| "missing name in vmstat")?;
                let found_value = pair.next().ok_or_else(|| "missing value in vmstat")?;
                // First check accumulative targets.
                if accumulate {
                    if found_name.starts_with(wanted_name) {
                        vmstat_values[i] += found_value.parse::<u64>()?;
                        advance_line = true;
                        advance_target = false;
                    } else {
                        // Try the next target, but don't consume the line.
                        advance_line = false;
                        advance_target = true;
                    }
                    continue;
                }
                // Then check for single-shot (not accumulated) fields.
                if found_name == wanted_name {
                    vmstat_values[i] = found_value.parse::<u64>()?;
                    advance_line = true;
                    advance_target = true;
                    continue;
                }
            }
            None => {
                if mandatory {
                    return Err(format!("vmstat: missing value: {}", wanted_name).into());
                } else {
                    vmstat_values[i] = 0;
                }
            }
        }
    }
    Ok(())
}

fn pread_u32(f: &File) -> Result<u32> {
    let mut buffer: [u8; 20] = [0; 20];
    // pread is safe to call with valid addresses and buffer length.
    let length = unsafe {
        libc::pread(
            f.as_raw_fd(),
            &mut buffer[0] as *mut u8 as *mut c_void,
            buffer.len(),
            0,
        )
    };
    if length < 0 {
        return Err("bad pread_u32".into());
    }
    if length == 0 {
        return Err("empty pread_u32".into());
    }
    Ok(String::from_utf8_lossy(&buffer[..length as usize])
        .trim()
        .parse::<u32>()?)
}

// Reads the content of file |f| starting at offset 0, up to |PAGE_SIZE|,
// stores it in |read_buffer|, and returns a slice of it as a string.
fn pread<'a>(f: &File, buffer: &'a mut [u8]) -> Result<&'a str> {
    // pread is safe to call with valid addresses and buffer length.
    let length = unsafe {
        libc::pread(
            f.as_raw_fd(),
            &mut buffer[0] as *mut u8 as *mut c_void,
            buffer.len(),
            0,
        )
    };
    if length == 0 {
        return Err("unexpected null pread".into());
    }
    if length < 0 {
        return Err(format!("pread failed: {}", strerror(errno())).into());
    }
    // Sysfs files contain only single-byte characters, so from_utf8_unchecked
    // would be safe for those files.  However, there's no guarantee that this
    // is only called on sysfs files.
    Ok(str::from_utf8(&buffer[..length as usize])?)
}

struct Watermarks {
    min: u32,
    low: u32,
    high: u32,
}

struct ZoneinfoFile(File);

impl ZoneinfoFile {
    // Computes and returns the watermark values from /proc/zoneinfo.
    fn read_watermarks(&mut self) -> Result<Watermarks> {
        let mut min = 0;
        let mut low = 0;
        let mut high = 0;
        let mut content = String::new();
        self.0.read_to_string(&mut content)?;
        for line in content.lines() {
            let items = line.split_whitespace().collect::<Vec<_>>();
            match items[0] {
                "min" => min += items[1].parse::<u32>()?,
                "low" => low += items[1].parse::<u32>()?,
                "high" => high += items[1].parse::<u32>()?,
                _ => {}
            }
        }
        Ok(Watermarks { min, low, high })
    }
}

trait Dbus {
    // Returns a vector of file descriptors that can be registered with a
    // Watcher.
    fn get_fds(&self) -> &Vec<RawFd>;
    // Processes incoming dbus events as indicated by |watcher|.  Returns
    // vectors of tab discards reported by chrome, and OOM kills reported by
    // the anomaly detector.
    fn process_dbus_events(&mut self, watcher: &mut FileWatcher) -> Result<Vec<(Event_Type, i64)>>;
}

#[cfg(not(test))]
struct GenuineDbus {
    connection: dbus::Connection,
    fds: Vec<RawFd>,
}

#[cfg(not(test))]
impl Dbus for GenuineDbus {
    fn get_fds(&self) -> &Vec<RawFd> {
        &self.fds
    }

    // Called if any of the dbus file descriptors fired.  Receives metrics
    // event signals, and return a vector of pairs, each pair containing the
    // event type and time stamp of each incoming event.
    //
    // Debugging example:
    //
    // INTERFACE=org.chromium.MetricsEventServiceInterface
    // dbus-monitor --system type=signal,interface=$INTERFACE
    // PAYLOAD=array:byte:0x10,0xa8,0xa2,0xc5,0x51
    // dbus-send --system --type=signal / $INTERFACE.ChromeEvent $PAYLOAD
    //
    fn process_dbus_events(&mut self, watcher: &mut FileWatcher) -> Result<Vec<(Event_Type, i64)>> {
        let mut events: Vec<(Event_Type, i64)> = Vec::new();
        for &fd in self.fds.iter() {
            if !watcher.has_fired_fd(fd)? {
                continue;
            }
            let handle = self
                .connection
                .watch_handle(fd, WatchEvent::Readable as libc::c_uint);
            for connection_item in handle {
                // Only consider signals.
                if let dbus::ConnectionItem::Signal(ref message) = connection_item {
                    // Only consider signals with "ChromeEvent" or
                    // "AnomalyEvent" members.
                    if let Some(member) = message.member() {
                        if &*member != "ChromeEvent" && &*member != "AnomalyEvent" {
                            // Do not report spurious "NameAcquired" signal to avoid spam.
                            if &*member != "NameAcquired" {
                                warn!("unexpected dbus signal member {}", &*member);
                            }
                            continue;
                        }
                    }
                    // Read first item in signal message as byte blob and
                    // parse blob into protobuf.
                    let raw_buffer: Vec<u8> = message.read1()?;
                    let mut protobuf = Event::new();
                    protobuf.merge_from_bytes(&raw_buffer)?;

                    let event_type = protobuf.get_field_type();
                    let time_stamp = protobuf.get_timestamp();
                    events.push((event_type, time_stamp))
                }
            }
        }
        Ok(events)
    }
}

#[cfg(not(test))]
impl GenuineDbus {
    // A GenuineDbus object contains a D-Bus connection used to receive
    // information from Chrome about events of interest (e.g. tab discards).
    fn new() -> Result<GenuineDbus> {
        let connection = Connection::get_private(BusType::System)?;
        let _m = connection.add_match(concat!(
            "type='signal',",
            "interface='org.chromium.AnomalyEventServiceInterface',",
            "member='AnomalyEvent'"
        ));
        let _m = connection.add_match(concat!(
            "type='signal',",
            "interface='org.chromium.MetricsEventServiceInterface',",
            "member='ChromeEvent'"
        ));
        let fds = connection.watch_fds().iter().map(|w| w.fd()).collect();
        Ok(GenuineDbus { connection, fds })
    }
}

// The main object.
struct Sampler<'a> {
    always_poll_fast: bool,       // When true, program stays in fast poll mode.
    paths: &'a Paths,             // Paths of files used by the program.
    dbus: Box<dyn Dbus>,          // Used to receive Chrome event notifications.
    low_mem_margin: u32, // Low-memory notification margin, assumed to remain constant in a boot session.
    sample_header: String, // The text at the beginning of each clip file.
    files: Files,        // Files kept open by the program.
    watcher: FileWatcher, // Maintains a set of files being watched for select().
    low_mem_watcher: FileWatcher, // A watcher for the low-mem device.
    clip_counter: usize, // Index of next clip file (also part of file name).
    sample_queue: SampleQueue, // A running queue of samples of vm quantities.
    current_available: u32, // Amount of "available" memory (in MB) at last reading.
    current_time: i64,   // Wall clock in ms at last reading.
    collecting: bool,    // True if we're in the middle of collecting a clip.
    timer: Box<dyn Timer>, // Real or mock timer.
    quit_request: bool,  // Signals a quit-and-restart request when testing.
}

impl<'a> Sampler<'a> {
    fn new(
        always_poll_fast: bool,
        paths: &'a Paths,
        timer: Box<dyn Timer>,
        dbus: Box<dyn Dbus>,
    ) -> Result<Sampler> {
        let mut low_mem_file_flags = OpenOptions::new();
        low_mem_file_flags.custom_flags(libc::O_NONBLOCK);
        low_mem_file_flags.read(true);
        let low_mem_file_option = open_with_flags_maybe(&paths.low_mem_device, &low_mem_file_flags)
            .map_err(|e| Error::LowMemFileError(e))?;
        if low_mem_file_option.is_none() {
            warn!("low-mem device: cannot open and will not use");
        }

        let mut watcher = FileWatcher::new();
        let mut low_mem_watcher = FileWatcher::new();

        if let Some(ref low_mem_file) = low_mem_file_option.as_ref() {
            watcher
                .set(&low_mem_file)
                .map_err(|e| Error::LowMemFDWatchError(e))?;
            low_mem_watcher
                .set(&low_mem_file)
                .map_err(|e| Error::LowMemWatcherError(e))?;
        }
        for fd in dbus.get_fds().iter().by_ref() {
            watcher.set_fd(*fd).map_err(|e| Error::DbusWatchError(e))?;
        }

        let files = Files {
            vmstat_file: File::open(&paths.vmstat)
                .map_err(|e| Error::VmstatFileError(Box::new(e)))?,
            runnables_file: File::open(&paths.runnables)
                .map_err(|e| Error::RunnablesFileError(Box::new(e)))?,
            available_file_option: open_maybe(&paths.available)
                .map_err(|e| Error::AvailableFileError(e))?,
            low_mem_file_option,
        };

        let sample_header = build_sample_header();

        let mut sampler = Sampler {
            always_poll_fast,
            dbus,
            low_mem_margin: read_int(&paths.low_mem_margin).unwrap_or(0),
            paths,
            sample_header,
            files,
            watcher,
            low_mem_watcher,
            sample_queue: SampleQueue::new(),
            clip_counter: 0,
            collecting: false,
            current_available: 0,
            current_time: 0,
            timer,
            quit_request: false,
        };
        sampler
            .find_starting_clip_counter()
            .map_err(|e| Error::StartingClipCounterMissingError(e))?;
        sampler
            .log_static_parameters()
            .map_err(|e| Error::LogStaticParametersError(e))?;
        Ok(sampler)
    }

    // Refresh cached time.  This should be called after system calls, which
    // can potentially block, but not if current_time is unused before the next call.
    fn refresh_time(&mut self) {
        self.current_time = self.timer.now();
    }

    // Collect a sample using the latest time snapshot.
    fn enqueue_sample(&mut self, sample_type: SampleType) -> Result<()> {
        let time = self.current_time; // to pacify the borrow checker
        self.enqueue_sample_at_time(sample_type, time)
    }

    // Collect a sample with an externally-generated time stamp.
    fn enqueue_sample_external(&mut self, sample_type: SampleType, time: i64) -> Result<()> {
        assert!(!sample_type.has_internal_timestamp());
        self.enqueue_sample_at_time(sample_type, time)
    }

    // Collects a sample of memory manager stats and adds it to the sample
    // queue, possibly overwriting an old value.  |sample_type| indicates the
    // type of sample, and |time| the system uptime at the time the sample was
    // collected.
    fn enqueue_sample_at_time(&mut self, sample_type: SampleType, time: i64) -> Result<()> {
        {
            let sample: &mut Sample = self.sample_queue.next_slot();
            sample.uptime = time;
            sample.sample_type = sample_type;
            sample.available = self.current_available;
            sample.runnables = get_runnables(&self.files.runnables_file)?;
            sample.info = if cfg!(test) {
                Sysinfo::fake_sysinfo()?
            } else {
                Sysinfo::sysinfo()?
            };
            get_vmstats(&self.files.vmstat_file, &mut sample.vmstat_values)?;
        }
        self.refresh_time();
        Ok(())
    }

    // Creates or overwrites a file in the memd log directory containing
    // quantities of interest.
    fn log_static_parameters(&self) -> Result<()> {
        let mut out = &mut OpenOptions::new()
            .write(true)
            .create(true)
            .truncate(true)
            .open(&self.paths.static_parameters)?;
        fprint_datetime(out)?;
        let low_mem_margin = read_int(&self.paths.low_mem_margin).unwrap_or(0);
        writeln!(out, "margin {}", low_mem_margin)?;

        let psv = &self.paths.procsysvm;
        log_from_procfs(&mut out, psv, "min_filelist_kbytes")?;
        log_from_procfs(&mut out, psv, "min_free_kbytes")?;
        log_from_procfs(&mut out, psv, "extra_free_kbytes")?;

        let mut zoneinfo = ZoneinfoFile {
            0: File::open(&self.paths.zoneinfo)?,
        };
        let watermarks = zoneinfo.read_watermarks()?;
        writeln!(out, "min_water_mark_kbytes {}", watermarks.min * 4)?;
        writeln!(out, "low_water_mark_kbytes {}", watermarks.low * 4)?;
        writeln!(out, "high_water_mark_kbytes {}", watermarks.high * 4)?;
        Ok(())
    }

    // Returns true if the program should go back to slow-polling mode (or stay
    // in that mode).  Returns false otherwise.  Relies on |self.collecting|
    // and |self.current_available| being up-to-date.  If the kernel does not
    // have the cros low-mem notifier, "margin" and "available" are both 0, and
    // this always returns false. (XXX should use a different way of detecting
    // medium pressure, but it's not critical since all cros devices have a
    // low-mem device.)
    fn should_poll_slowly(&self) -> bool {
        !self.collecting
            && !self.always_poll_fast
            && self.low_mem_margin > 0
            && self.current_available > self.low_mem_margin + LOW_MEM_DANGER_THRESHOLD_MB
    }

    // Sits mostly idle and checks available RAM at low frequency.  Returns
    // when available memory gets "close enough" to the tab discard margin.
    fn slow_poll(&mut self) -> Result<()> {
        debug!("entering slow poll at {}", self.current_time);
        // Idiom for do ... while.
        while {
            let fired_count = {
                let watcher = &mut self.watcher;
                watcher.watch(&SLOW_POLL_PERIOD_DURATION, &mut *self.timer)?
            };
            debug!("fired count: {} at {}", fired_count, self.timer.now());
            self.quit_request = self.timer.quit_request();
            if let Some(ref available_file) = self.files.available_file_option.as_ref() {
                self.current_available = pread_u32(available_file)?;
            }
            self.refresh_time();
            self.should_poll_slowly() && !self.quit_request && fired_count == 0
        } {}
        Ok(())
    }

    // Collects timer samples at fast rate.  Also collects event samples.
    // Samples contain various system stats related to kernel memory
    // management.  The samples are placed in a circular buffer.  When
    // something "interesting" happens, (for instance a tab discard, or a
    // kernel OOM-kill) the samples around that event are saved into a "clip
    // file".
    fn fast_poll(&mut self) -> Result<()> {
        let mut earliest_start_time = self.current_time;
        debug!("entering fast poll at {}", earliest_start_time);

        // Collect the first timer sample immediately upon entering.
        self.enqueue_sample(SampleType::Timer)?;
        // Keep track if we're in a low-mem state.  Initially assume we are
        // not.
        let mut in_low_mem = false;
        // |clip_{start,end}_time| are the collection start and end time for
        // the current clip.  Their value is valid only when |self.collecting|
        // is true.
        let mut clip_start_time = self.current_time;
        let mut clip_end_time = self.current_time;
        // |final_collection_time| indicates when we should stop collecting
        // samples for any clip (either the current one, or the next one).  Its
        // value is valid only when |self.collecting| is true.
        let mut final_collection_time = self.current_time;
        let null_duration = Duration::from_secs(0);

        // |self.collecting| is true when we're in the middle of collecting a clip
        // because something interesting has happened.
        self.collecting = false;

        // Poll/select loop.
        loop {
            // Assume event is not interesting (since most events
            // aren't). Change this to true for some event types.
            let mut event_is_interesting = false;

            let watch_start_time = self.current_time;
            let fired_count = {
                let watcher = &mut self.watcher;
                watcher.watch(&FAST_POLL_PERIOD_DURATION, &mut *self.timer)?
            };
            self.quit_request = self.timer.quit_request();
            if let Some(ref available_file) = self.files.available_file_option.as_ref() {
                self.current_available = pread_u32(available_file)?;
            }
            self.refresh_time();

            // Record a sample when we sleep too long.  Such samples are
            // somewhat redundant as they could be deduced from the log, but we
            // wish to make it easier to detect such (rare, we hope)
            // occurrences.
            if watch_start_time > self.current_time + UNREASONABLY_LONG_SLEEP {
                warn!(
                    "woke up at {} after unreasonable {} sleep",
                    self.current_time,
                    self.current_time - watch_start_time
                );
                self.enqueue_sample(SampleType::Sleeper)?;
            }

            // The low_mem file is level-triggered, not edge-triggered (my bad)
            // so we don't watch it when memory stays low, because it would
            // fire continuously.  Instead we poll it at every event, and when
            // we detect a low-to-high transition we start watching it again.
            // Unfortunately this requires an extra select() call: however we
            // don't expect to spend too much time in this state (and when we
            // do, this is the least of our worries).
            if in_low_mem
                && self
                    .low_mem_watcher
                    .watch(&null_duration, &mut *self.timer)?
                    == 0
            {
                // Refresh time since we may have blocked.  (That should
                // not happen often because currently the run times between
                // sleeps are well below the minimum timeslice.)
                self.current_time = self.timer.now();
                debug!("leaving low mem at {}", self.current_time);
                in_low_mem = false;
                self.enqueue_sample(SampleType::LeaveLowMem)?;
                self.watcher
                    .set(&self.files.low_mem_file_option.as_ref().unwrap())?;
            }

            if fired_count == 0 {
                // Timer event.
                self.enqueue_sample(SampleType::Timer)?;
            } else {
                // See comment above about watching low_mem.
                let low_mem_has_fired = !in_low_mem
                    && match self.files.low_mem_file_option {
                        Some(ref low_mem_file) => self.watcher.has_fired(low_mem_file)?,
                        _ => false,
                    };
                if low_mem_has_fired {
                    debug!("entering low mem at {}", self.current_time);
                    in_low_mem = true;
                    self.enqueue_sample(SampleType::EnterLowMem)?;
                    let fd = self.files.low_mem_file_option.as_ref().unwrap().as_raw_fd();
                    self.watcher.clear_fd(fd)?;
                    // Make this interesting at least until chrome events are
                    // plumbed, maybe permanently.
                    event_is_interesting = true;
                }

                // Check for dbus events.
                let events = self.dbus.process_dbus_events(&mut self.watcher)?;
                if events.len() > 0 {
                    debug!("dbus events at {}: {:?}", self.current_time, events);
                    event_is_interesting = true;
                }
                for event in events {
                    let sample_type = match event.0 {
                        Event_Type::TAB_DISCARD => SampleType::TabDiscard,
                        Event_Type::OOM_KILL => SampleType::OomKillBrowser,
                        Event_Type::OOM_KILL_KERNEL => SampleType::OomKillKernel,
                        _ => {
                            warn!("unknown event type {:?}", event.0);
                            continue;
                        }
                    };
                    debug!("enqueue {:?}, {:?}", sample_type, event.1);
                    self.enqueue_sample_external(sample_type, event.1)?;
                }
            }

            // Arrange future saving of samples around interesting events.
            if event_is_interesting {
                // Update the time intervals to ensure we include all samples
                // of interest in a clip.  If we're not in the middle of
                // collecting a clip, start one.  If we're in the middle of
                // collecting a clip which can be extended, do that.
                final_collection_time = self.current_time + COLLECTION_DELAY_MS;
                if self.collecting {
                    // Check if the current clip can be extended.
                    if clip_end_time < clip_start_time + CLIP_COLLECTION_SPAN_MS {
                        clip_end_time =
                            final_collection_time.min(clip_start_time + CLIP_COLLECTION_SPAN_MS);
                        debug!("extending clip to {}", clip_end_time);
                    }
                } else {
                    // Start the clip collection.
                    self.collecting = true;
                    clip_start_time =
                        earliest_start_time.max(self.current_time - COLLECTION_DELAY_MS);
                    clip_end_time = self.current_time + COLLECTION_DELAY_MS;
                    debug!(
                        "starting new clip from {} to {}",
                        clip_start_time, clip_end_time
                    );
                }
            }

            // Check if it is time to save the samples into a file.
            if self.collecting && self.current_time > clip_end_time - SAMPLING_PERIOD_MS {
                // Save the clip to disk.
                debug!(
                    "[{}] saving clip: ({} ... {}), final {}",
                    self.current_time, clip_start_time, clip_end_time, final_collection_time
                );
                self.save_clip(clip_start_time)?;
                self.collecting = false;
                earliest_start_time = clip_end_time;
                // Need to schedule another collection?
                if final_collection_time > clip_end_time {
                    // Continue collecting by starting a new clip.  Note that
                    // the clip length may be less than CLIP_COLLECTION_SPAN.
                    // This happens when event spans overlap, and also if we
                    // started fast sample collection just recently.
                    assert!(final_collection_time <= clip_end_time + CLIP_COLLECTION_SPAN_MS);
                    clip_start_time = clip_end_time;
                    clip_end_time = final_collection_time;
                    self.collecting = true;
                    debug!(
                        "continue collecting with new clip ({} {})",
                        clip_start_time, clip_end_time
                    );
                    // If we got stuck in the select() for a very long time
                    // because of system slowdown, it may be time to collect
                    // this second clip as well.  But we don't bother, since
                    // this is unlikely, and we can collect next time around.
                    if self.current_time > clip_end_time {
                        debug!(
                            "heavy slowdown: postponing collection of ({}, {})",
                            clip_start_time, clip_end_time
                        );
                    }
                }
            }
            if self.should_poll_slowly() || (self.quit_request && !self.collecting) {
                break;
            }
        }
        Ok(())
    }

    // Returns the clip file pathname to be used after the current one,
    // and advances the clip counter.
    fn next_clip_path(&mut self) -> PathBuf {
        let name = format!("memd.clip{:03}.log", self.clip_counter);
        self.clip_counter = modulo(self.clip_counter as isize + 1, MAX_CLIP_COUNT);
        self.paths.log_directory.join(name)
    }

    // Finds and sets the starting value for the clip counter in this session.
    // The goal is to preserve the most recent clips (if any) from previous
    // sessions.
    fn find_starting_clip_counter(&mut self) -> Result<()> {
        self.clip_counter = 0;
        let mut previous_time = std::time::UNIX_EPOCH;
        loop {
            let path = self.next_clip_path();
            if !path.exists() {
                break;
            }
            let md = std::fs::metadata(path)?;
            let time = md.modified()?;
            if time < previous_time {
                break;
            } else {
                previous_time = time;
            }
        }
        // We found the starting point, but the counter has already advanced so we
        // need to backtrack one step.
        self.clip_counter = modulo(self.clip_counter as isize - 1, MAX_CLIP_COUNT);
        Ok(())
    }

    // Stores samples of interest in a new clip log, and remove those samples
    // from the queue.
    fn save_clip(&mut self, start_time: i64) -> Result<()> {
        let path = self.next_clip_path();
        let mut out = &mut OpenOptions::new()
            .write(true)
            .create(true)
            .truncate(true)
            .open(path)?;

        // Print courtesy header.  The first line is the current time.  The
        // second line lists the names of the variables in the following lines,
        // in the same order.
        fprint_datetime(out)?;
        out.write_all(self.sample_header.as_bytes())?;
        // Output samples from |start_time| to the head.
        self.sample_queue.output_from_time(&mut out, start_time)?;
        // The queue is now empty.
        self.sample_queue.reset();
        Ok(())
    }
}

// Prints |name| and value of entry /pros/sys/vm/|name| (or 0, if the entry is
// missing) to file |out|.
fn log_from_procfs(out: &mut File, dir: &Path, name: &str) -> Result<()> {
    let procfs_path = dir.join(name);
    let value = read_int(&procfs_path).unwrap_or(0);
    writeln!(out, "{} {}", name, value)?;
    Ok(())
}

// Outputs readable date and time to file |out|.
fn fprint_datetime(out: &mut File) -> Result<()> {
    let local: DateTime<Local> = Local::now();
    writeln!(out, "{}", local)?;
    Ok(())
}

#[derive(Copy, Clone, Debug)]
enum SampleType {
    EnterLowMem,    // Entering low-memory state, from the kernel low-mem notifier.
    LeaveLowMem,    // Leaving low-memory state, from the kernel low-mem notifier.
    OomKillBrowser, // Chrome browser letting us know it detected OOM kill.
    OomKillKernel,  // Anomaly detector letting us know it detected OOM kill.
    Sleeper,        // Memd was not running for a long time.
    TabDiscard,     // Chrome browser letting us know about a tab discard.
    Timer,          // Event was produced after FAST_POLL_PERIOD_DURATION with no other events.
    Uninitialized,  // Internal use.
}

impl Default for SampleType {
    fn default() -> SampleType {
        SampleType::Uninitialized
    }
}

impl fmt::Display for SampleType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl SampleType {
    // Returns true if the timestamp for this sample type is generated
    // internally.  This knowledge is used in outputting samples to clip files,
    // because the timestamps of samples generated externally may be skewed.
    fn has_internal_timestamp(&self) -> bool {
        match self {
            &SampleType::TabDiscard | &SampleType::OomKillBrowser | &SampleType::OomKillKernel => {
                false
            }
            _ => true,
        }
    }
}

impl SampleType {
    // Returns the 6-character(max) identifier for a sample type.
    fn name(&self) -> &'static str {
        match *self {
            SampleType::EnterLowMem => "lowmem",
            SampleType::LeaveLowMem => "lealow",
            SampleType::OomKillBrowser => "oomkll", // OOM from chrome
            SampleType::OomKillKernel => "keroom",  // OOM from kernel
            SampleType::Sleeper => "sleepr",
            SampleType::TabDiscard => "discrd",
            SampleType::Timer => "timer",
            SampleType::Uninitialized => "UNINIT",
        }
    }
}

// Path names of various system files, mostly in /proc, /sys, and /dev.  They
// are collected into this struct because they get special values when testing.
#[derive(Clone)]
pub struct Paths {
    vmstat: PathBuf,
    available: PathBuf,
    runnables: PathBuf,
    low_mem_margin: PathBuf,
    low_mem_device: PathBuf,
    log_directory: PathBuf,
    static_parameters: PathBuf,
    zoneinfo: PathBuf,
    procsysvm: PathBuf,
    testing_root: PathBuf,
}

// Returns a file name that replaces |name| when testing.
fn test_filename(testing: bool, testing_root: &str, name: &str) -> String {
    if testing {
        testing_root.to_string() + name
    } else {
        name.to_owned()
    }
}

// This macro constructs a "normal" Paths object when |testing| is false, and
// one that mimics a root filesystem in a temporary directory when |testing| is
// true.
macro_rules! make_paths {
    ($testing:expr, $root:expr,
     $($name:ident : $e:expr,)*
    ) => (
        Paths {
            testing_root: PathBuf::from($root),
            $($name: PathBuf::from(test_filename($testing, $root, &($e).to_string()))),*
        }
    )
}

// All files that are to be left open go here.  We keep them open to reduce the
// number of syscalls.  They are mostly files in /proc and /sys.
struct Files {
    vmstat_file: File,
    runnables_file: File,
    // These files might not exist.
    available_file_option: Option<File>,
    low_mem_file_option: Option<File>,
}

fn build_sample_header() -> String {
    let mut s = "uptime type load freeram freeswap procs runnables available".to_string();
    for vmstat in VMSTATS.iter() {
        s = s + " " + vmstat.0;
    }
    s + "\n"
}

fn main() {
    let mut always_poll_fast = false;
    let mut debug_log = false;

    let args: Vec<String> = std::env::args().collect();
    for arg in &args[1..] {
        match arg.as_ref() {
            "always-poll-fast" => always_poll_fast = true,
            "debug-log" => debug_log = true,
            _ => panic!("usage: memd [always-poll-fast|debug-log]*"),
        }
    }

    let log_level = if debug_log {
        log::LevelFilter::Debug
    } else {
        log::LevelFilter::Warn
    };
    syslog::init(syslog::Facility::LOG_USER, log_level, Some("memd"))
        .expect("cannot initialize syslog");

    // Unlike log!(), warn!() etc., panic!() is not redirected by the syslog
    // facility, instead always goes to stderr, which can get lost.  Here we
    // provide our own panic hook to make sure that the panic message goes to
    // the syslog as well.
    let default_panic = std::panic::take_hook();
    std::panic::set_hook(Box::new(move |panic_info| {
        error!("memd: {}", panic_info);
        default_panic(panic_info);
    }));

    warn!("memd started");
    run_memory_daemon(always_poll_fast).expect("memd failed");
}

// Creates a directory for testing, if testing.  Otherwise
// returns None
fn make_testing_dir() -> Option<TempDir> {
    if cfg!(test) {
        Some(TempDir::new().expect("cannot create temp dir"))
    } else {
        None
    }
}

#[test]
fn memory_daemon_test() {
    env_logger::init();
    run_memory_daemon(false).expect("run_memory_daemon error");
}

#[test]
fn read_loadavg_test() {
    test::read_loadavg();
}

#[test]
fn read_vmstat_test() {
    let testing_dir_option = make_testing_dir();
    let paths = get_paths(testing_dir_option);
    test::read_vmstat(&paths);
}

/// Regression test for https://crbug.com/1058463. Ensures that output_from_time doesn't read
/// samples outside of the valid range.
#[test]
fn queue_loop_test() {
    test::queue_loop();
}

fn get_paths(root: Option<TempDir>) -> Paths {
    // make_paths! returns a Paths object initializer with these fields.
    let testing_root = match root {
        Some(tmpdir) => tmpdir.path().to_str().unwrap().to_string(),
        None => "/".to_string(),
    };
    make_paths!(
        cfg!(test),
        &testing_root,
        vmstat:            "/proc/vmstat",
        available:         LOW_MEM_SYSFS.to_string() + "/available",
        runnables:         "/proc/loadavg",
        low_mem_margin:    LOW_MEM_SYSFS.to_string() + "/margin",
        low_mem_device:    LOW_MEM_DEVICE,
        log_directory:     LOG_DIRECTORY,
        static_parameters: LOG_DIRECTORY.to_string() + "/" + STATIC_PARAMETERS_LOG,
        zoneinfo:          "/proc/zoneinfo",
        procsysvm:         "/proc/sys/vm",
    )
}

fn run_memory_daemon(always_poll_fast: bool) -> Result<()> {
    let test_dir_option = make_testing_dir();
    let paths = get_paths(test_dir_option);

    #[cfg(test)]
    {
        test::setup_test_environment(&paths);
        let var_log = &paths.log_directory.parent().unwrap();
        std::fs::create_dir_all(var_log).map_err(|e| Error::CreateLogDirError(Box::new(e)))?;
    }

    // Make sure /var/log/memd exists.  Create it if not.  Assume /var/log
    // exists.  Panic on errors.
    if !paths.log_directory.exists() {
        create_dir(&paths.log_directory).map_err(|e| Error::CreateLogDirError(Box::new(e)))?
    }

    #[cfg(test)]
    {
        test::test_loop(always_poll_fast, &paths);
        test::teardown_test_environment(&paths);
        Ok(())
    }

    #[cfg(not(test))]
    {
        let timer = Box::new(GenuineTimer {});
        let dbus = Box::new(GenuineDbus::new()?);
        let mut sampler = Sampler::new(always_poll_fast, &paths, timer, dbus)?;
        loop {
            // Run forever, alternating between slow and fast poll.
            sampler.slow_poll()?;
            sampler.fast_poll()?;
        }
    }
}
