use std::cell::RefCell;

use crate::simulator::machine::Machine;

use super::thread_manager::ThreadManager;

/// # System
/// 
/// This structure represents the state of the threads running on the operating system.
/// It contains references to the following:
/// 
/// - The simulated machine
/// - The current running thread
/// - The list of active threads
/// - The thread to be destroyed next
/// - The scheduler which acts upon these threads
#[derive(PartialEq)]
pub struct System<'a> {
    g_machine: RefCell<Machine>,
    thread_manager: ThreadManager<'a>
}

impl<'a> System<'a> {

    /// System constructor
    pub fn new(machine: Machine) -> System<'a> {
        Self {
            g_machine: RefCell::new(machine),
            thread_manager: ThreadManager::new()
        }
    }

    pub fn freeze(&'a mut self) {
        self.thread_manager.system.set(Option::Some(self));
    }

    // GETTERS

    /// Returns the Machine
    /// 
    /// Useful to access RAM, devices, ...
    pub fn get_g_machine(&self) -> &RefCell<Machine> {
        &self.g_machine
    }

    // Setters

    /// Assign a machine to the system
    pub fn set_g_machine(&mut self, machine: RefCell<Machine>) {
        self.g_machine = machine
    }

}

#[derive(PartialEq)]
pub enum ObjectType {
    SemaphoreType,
    LockType,
    ConditionType,
    FileType,
    ThreadType,
    InvalidType
}