use std::sync::Mutex;
use std::cell::RefCell;

use super::info::Info;
use super::opts::Opts;
use super::plan::Plan;

type Inner = Mutex<RefCell<Info>>;

#[derive(Debug, Default)]
pub(super) struct InfoRef(Inner);

impl InfoRef {
    pub(super) fn create(parent_plan: &Plan, opts: &Opts) -> Self
    {
	Self(Mutex::new(RefCell::new(Info::new(parent_plan, opts))))
    }

    pub fn with<F,R>(&self, f: F) -> R
    where
	 F: FnOnce(&Info) -> R
    {
	use std::ops::Deref;

	f(self.lock().unwrap().borrow().deref())
    }

    pub fn with_mut<F,R>(&self, f: F) -> R
    where
	 F: FnOnce(&mut Info) -> R
    {
	use std::ops::DerefMut;

	f(self.lock().unwrap().borrow_mut().deref_mut())
    }
}

impl std::ops::Deref for InfoRef {
    type Target = Mutex<RefCell<Info>>;

    fn deref(&self) -> &Self::Target {
	&self.0
    }
}
