// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::fmt;

use std::path::Path;
use std::path::PathBuf;

use rand::Rng;
use rand::ThreadRng;
use rand::thread_rng;

#[derive(Clone, Debug, Eq, PartialEq)]
/// A list of very basic states a SimDev can be in.
pub enum State {
    OK,
    FAILED,
}

#[derive(Clone)]
/// A simulated device.
pub struct SimDev {
    pub name: PathBuf,
    rng: ThreadRng,
    pub state: State,
}

/// Implement Debug for SimDev explicitly as ThreadRng does not derive it.
/// See: https://github.com/rust-lang-nursery/rand/issues/118
impl fmt::Debug for SimDev {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{{SimDev {:?} {:?}", self.name, self.state)
    }
}


impl SimDev {
    /// Generates a new device from any path.
    pub fn new_dev(name: &Path) -> Box<SimDev> {
        Box::new(SimDev {
            name: name.to_owned(),
            rng: thread_rng(),
            state: State::OK,
        })
    }

    /// Function that causes self to progress probabilistically to a new state.
    pub fn update(&mut self) {
        if self.rng.gen_weighted_bool(8) {
            self.state = State::FAILED;
        }
    }

    /// Checks usability of a SimDev
    pub fn usable(&self) -> bool {
        self.state == State::OK
    }
}

Add an implementation for SimDev.
Add an implementation for SimDev.

Signed-off-by: mulhern <7b51bcf507bcd7afb72bf8663752c0ddbeb517f6@redhat.com>
