use std::sync::{Arc, atomic::AtomicBool, mpsc};
use std::sync::atomic::AtomicIsize;
use std::time::Duration;
use arc_swap::ArcSwap;
use common::prelude::Register;

use super::interrupts::Interrupt;
pub struct SharedState {
    pub proc: ArcSwap<ProcessorSnapshot>,

    pub reseting: AtomicBool,
    pub paused: AtomicBool,
    pub update_req: AtomicBool,
    pub interrupt_queue: mpsc::Sender<Interrupt>,
}

impl SharedState {
    pub fn new(sender: mpsc::Sender<Interrupt>) -> Self {
        Self {
            reseting: AtomicBool::new(false),
            proc: ArcSwap::new(Arc::new(ProcessorSnapshot::default())),

            paused: AtomicBool::new(true),
            interrupt_queue: sender,
            update_req: AtomicBool::new(false),
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum RunningState {
    Paused,
    Halted,
    Running,
    Shutdown,
    Breakpoint(u32),
}

#[derive(Debug, Clone)]
pub struct ProcessorSnapshot {
    pub running: RunningState,
    pub clock: usize,
    pub time: Duration,
    pub registers: [u32; Register::COUNT as usize],
}

impl Default for ProcessorSnapshot {
    fn default() -> Self {
        Self {
            running: RunningState::Paused,
            clock: 0,
            time: Duration::ZERO,
            registers: [0; Register::COUNT as usize],
        }
    }
}
